多线程

来源:互联网 发布:熊猫书院 知乎 编辑:程序博客网 时间: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();
}
}

原创粉丝点击