进程:正在进行中的程序(直译);
线程:进程中一个负责程序执行的控制单元;(也叫执行路径)
–一个进程中可以有多个执行路径,称之为多线程。
–一个进程中至少有一个线程。
创建线程方式一:继承Thread类
1.继承Thread类;
2.然后覆盖Thread类里的run方法;
3.然后直接创建Thread的子类来创建线程;
4.调用start方法开启线程并调用线程的任务run方法执行。
创建线程的第二种方式:实现Runable接口
1.定义类实现Runable接口。
2.覆盖接口中的run方法,将线程的任务代码,封装到run方法中。
3.通过Thread类创建线程对象,并将Runable接口的子类对象作为Thread类的构造函数的参数进行传递。
4.调用线程对象的start方法开启线程。
实现Runable接口的好处:
1.将线程的任务从线程的子类中分离出来,进行了单独的封装,
按照面向对象的思想将任务封装成对象。
2.避免了Java单继承的局限性。
所以创建线程的第二种方式较为常用。
线程安全问题产生的原因:
1.多线程在操作共享的数据。
2.操作共享数组的线程有多条。
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
在Java中用同步代码块就就可以解决这个问题。
–同步的好处:解决了线程安全的问题。
–弊端:相对降低了效率。因为同步外的线程都会判断同步锁。
**同步函数使用的锁是this;
**静态函数使用的同步锁是:该函数字节码文件,可以用getClass方法获取,也可以用当前类名.class 表示。
进行银行存款的案例,关于同步
class Bank
{
private int sum;
private Object obj = new Object();
public synchronized void add(int sum) 同步函数和同步代码快都可以解决同步问题。
{
// synchronized(obj) 这样也是可以的。
//{
sum += num;
try
{ Thread.sleep(10); }catch(interruptedException e){};
System.out.println("sum" + sum);
//}
}
}
class Cus implements Runable
{
private Bank b = new Bank();
public void run()
{
for(int x=0; x<3, x++)
{
b.add(100);
}
}
}
class BankDemo
{
public static void main(String[] args)
{
Cus c = new Cus(c);
Thread t1 = new Thread(c);
Thread t2 = new Thread(c);
t1.start();
t2.start();
}
}
多线程下的单例模式:
饿汉式:
class Single
{
private static final Single s = new Single();
private Single(){};
public static Single getInstance()
{ return s; }
}
懒汉式(面试时候用):
class Single
{
private static Single s = null;
private Single(){};
publci static Single getInstance()
{
if(s = null)
{
synchronized(Single.class)
{
if(s = null)
s = new Single();
}
}
return s;
}
}
死锁实例
class Test implements Runable
{
private boolean flag;
Test(boolean flag)
{
this.flag = flag;
}
public void run
{
if(flag)
{
while(true)
{
synchronized(MyLocka)
{
System.out.print(Thread.currentThread.getName()+"if...locka");
synchronized(MyLockb)
{
System.out.print(Thread.currentThread.getName()+"if...lockb");
}
}
}
}
else
{
while(true){
synchronized(MyLockb)
{
System.out.print(Thread.currentThread.getName()+"else...lockb");
synchronized(MyLocka)
{
System.out.print(Thread.currentThread.getName()+"else...locka");
}
}
}
}
}
}
class MyLock
{
public static final Object locka = new Object();
public static final Object lockb = new Object();
}
class DeadLockTest
{
public static void main(String[] args)
{
Test a = new Test(true);
Test b = new Test(false);
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
t1.start();
t2.start();
}
}