java学习日记(6)____多线程的安全问题与死锁的产生
在java多线程中,最让我头大的还是安全性问题以及处理(synchronized这个关键字还真长),还有后来的死锁问题,也就是同 步中嵌套同步,先说说安全问题,不过说到这就要涉及到了线程的集中状态了,线程有这样几种状态 1,运行 2,冻结 3,消亡 4,临时状态 , 说简单点就是有执行资格,但是没有执行权,这取决于CPU,它想执行谁就执行谁,所以线程自己控制不了,这 样一来就造成了线程安全的问题了,
class Ticket implements Runnable
{
private int tick = 1000;
Object obj = new Object();
public void run()
{
while(true)
{
synchronized(obj)
{
if(tick>0)
{
//try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"....sale : "+
tick--);
}
}
}
}
}
线程在执行这段代码的时候,当票数只剩下一张的时候,有一个线程读到if判断还有一张,就在准备执行 答应语句的时候,这
个时候cpu没有执行它了,而是去执行另外的线程了,所以原先的线程就会停在那中间不动,而当第二个线程进来的时候判断还
有一张所以进来了,不过同样cpu又放弃它了,这样一来打印出来的票数会出现0 和-1,所以就不安全了。不过java中有专门的
语句来处理,同步代码块synchronized
synchronized(obj)
{
if(tick>0)
{
//try{Thread.sleep(10);}catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"....sale : "+
tick--);
}
}
同步代码块的意思就是 让那些执行共享数据的语句必须同步执行,一个线程在执行的时候,另外的线程不可能进来,因为有了
里面锁的存在。只有拿到锁了才进的来。
不过同步代码块虽然能够处理安全问题,但是同步代码快没用好的话,同样会造成死锁!也就是同步中嵌套同步
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");
}
}
}
}
为了避免死锁的出现,大家一定要小心,上面的例子就是双方都需要对方的锁,然后都不释放出来,最终造成死锁,程序停止