多线程
来源:互联网 发布:熊猫书院 知乎 编辑:程序博客网 时间:2024/06/10 07:28
1、线程的四种状态
被创建----start()-------->运行<----sleep(time)变成冻结,sleep时间到了就开始运行或wait()一直冻结与notify()唤醒变成运行---->冻结(释放执行权的同时释放执行资格)
|
|run方法结束,线程的任务结束stop()
消亡
CPU的执行资格:可以被CPU处理,在处理队列中排队
cup的执行权:正在被CPU处理
临时阻塞状态:具备执行资格,但是不具备执行权,正在等待执行权。
2、创建线程的第一种方式:继承Thread类
第二种方式实现Runnable接口,实现run方法,通过Thread类创建线程对象并将runnable接口的子类对象作为Thread类构造函数的参数进行传递。最后调用线程对象的start方法开启线程。
Demo d=new Demo(); Thread t=new Thread(d); demo实现了runnable接口。
3、线程安全产生的原因
*多个线程在操作共享的数据
*操作共享数据的线程代码有多条
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
4、解决思路
就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程不可以参与运算。
在java中用同步代码块解决这个问题
同步代码块
synchronized(对象){
同步代码块;
}
好处:解决了线程的安全问题
弊端:相对降低了效率
同步的前提:必须有多个线程使用同一个锁
同步函数:public synchronized void add(int num)
同步函数使用的锁是this。
同步函数和同步代码块的区别:同步函数的锁是固定的this,同步代码块的锁是任意的对象。
建议使用同步代码块。
静态的同步函数使用的锁是:该函数所属字节码文件对象,可以使用(this.getClass)getClass方法获取,也可以使用当前类名.class获取
5、死锁
场景情景:同步的嵌套
class Test implements Runnable
{
private boolean flag;
Test(boolean flag)
{
this.flag = flag;
}
public void run()
{
if(flag)
{
while(true)
synchronized(MyLock.locka)
{
System.out.println(Thread.currentThread().getName()+"..if locka....");
synchronized(MyLock.lockb){
System.out.println(Thread.currentThread().getName()+"..if lockb....");
}
}
}
else
{
while(true)
synchronized(MyLock.lockb)
{
System.out.println(Thread.currentThread().getName()+"..else lockb....");
synchronized(MyLock.locka)
{
System.out.println(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();
}
}