教你学会java基础多线程系列文章之中级篇(一)

   看完多线程初级篇的童鞋就可以看线程中级篇(一)了

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);   //a1先抢到资源进来了, 然后这里a1被sleep了。然后a2进来了,票数t-1=1.   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)同步锁注释掉,来说明问题

运行结果如下:

竟然出现了0号票。。。(我们去12306网站{{允许我给12306打个小广告}}上是买不到0号票的好吗~~)

原因我就以注释的形式写在代码中。

       该程序中导致不安全性的问题,就是没有再次判断if条件,我们想象着在if前加一把锁,当有线程进入时,就把锁给锁上了,其他线程看到锁被锁上后,就只好在门口等待。

大家可以把这个与火车上的厕所联系在一起,有人进入厕所后,就会转动门把,把门锁住,其他人看到锁被锁住,就知道里面有人,而在外面等待!

      synchronized(obj)这个就是用来实现锁的问题!括号中用到的就叫锁,可以是任意的唯一对象,比如本文中新建的Object obj对象,也可以是类对象
ThreadDemoone.class或者Thread2.class,只要是唯一的对象即可。



你可能感兴趣的:(自学ing)