看完多线程初级篇的童鞋就可以看线程中级篇(一)了
class ThreadDemoone implements Runnable{
private static int t=120;
Object obj=new Object();
@Override
public void run(){
while(true){
//synchronized(obj){
if(t>0){ //假设a1,a2俩个线程同时访问,票数t==1,
try {
Thread.sleep(20); //<span style="font-family: Arial, Helvetica, sans-serif;">a1先抢到资源进来了, 然后</span>这里a1被sleep了。然后a2进来了,<span style="font-family: Arial, Helvetica, sans-serif;">票数t-1=1. </span>a2也被sleep了
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//假设a1先复活了(a1就是每次都能抢到。。好巧~~a2...别怪我)
//打印票数t=1,接着票数t-1=0. a1执行结束了,退出 此时票数已经等于0,按道理不可以在进行售票了
//a2活了 这时a2已经进入到if里面,即使t=0,却没有再判断了,而是直接把t=0打印,接着票数t-1=-1.
System.out.println(Thread.currentThread().getName()+"--sale....:"+t--);
}
//}
}
}
}
public class Thread2 {
public static void main(String[] args) {
ThreadDemoone t1=new ThreadDemoone();
Thread a1=new Thread(t1);
Thread a2=new Thread(t1);
a1.start();
a2.start();
}
}
大家看上面这段简单的卖票程序,我先把synchronized(obj)同步锁注释掉,来说明问题
运行结果如下:
原因我就以注释的形式写在代码中。
该程序中导致不安全性的问题,就是没有再次判断if条件,我们想象着在if前加一把锁,当有线程进入时,就把锁给锁上了,其他线程看到锁被锁上后,就只好在门口等待。
大家可以把这个与火车上的厕所联系在一起,有人进入厕所后,就会转动门把,把门锁住,其他人看到锁被锁住,就知道里面有人,而在外面等待!
synchronized(obj)这个就是用来实现锁的问题!括号中用到的就叫锁,可以是任意的唯一对象,比如本文中新建的Object obj对象,也可以是类对象
<span style="font-family: Arial, Helvetica, sans-serif;">ThreadDemoone</span><span style="font-family: Arial, Helvetica, sans-serif;">.class或者Thread2.class,只要是唯一的对象即可。</span>