随笔-10  评论-11  文章-20  trackbacks-0
        在应用多线程的时候,会出现多线程并发的情况。特别是在资源共享的时候,很容易出现问题,比如访问的资源出错,或者访问的是同一个资源。具体通过下面这个例子来说明问题:
        这是模拟车站买票的例子,假如这个车站有三个窗口同时卖同一班客车的车票,当我们没有使用synchronized同步块的时候就会出现同时卖出同一张车票的现象或者是没有车票了依旧在调出,出现负数的情况:
例如代码:

class MyThread01 implements Runnable
{
 private int ticket = 30;                           //共享的总资源,票数为30
 public void run()
 {
  for(int i = 0 ; i < 100 ; i++)
  {
    if(this.ticket>0){
     try{
      Thread.sleep(100);
     }catch(InterruptedException e){
      e.printStackTrace();
     }
     System.out.println(Thread.currentThread().getName()+"卖出一张,剩余票数"+(--this.ticket));
     }
   }
 }
}


public class Thread01 {
 public static void main(String args[])
 {
  MyThread01 mt = new MyThread01();
                                                                  //初始出三个线程
  Thread t1 = new Thread(mt,"yi");
  Thread t2 = new Thread(mt,"er");
  Thread t3 = new Thread(mt,"san");
                                                                  //启动这三个线程
  t1.start();
  t2.start();
  t3.start();
 }

}


那么这段代码运行就会出现类似如下的结果:
yi卖出一张,剩余票数5
san卖出一张,剩余票数4
er卖出一张,剩余票数3
yi卖出一张,剩余票数2
san卖出一张,剩余票数1
er卖出一张,剩余票数0
yi卖出一张,剩余票数-1
san卖出一张,剩余票数-2

最后两行出现了不合逻辑要求的负数。

那么当我们加上sychronized同步块后:
代码如下:

class MyThread01 implements Runnable
{
 private int ticket = 30;
 public void run()
 {
  for(int i = 0 ; i < 100 ; i++)
  {
   synchronized(this){//同步块
    if(this.ticket>0){
     try{
      Thread.sleep(100);
     }catch(InterruptedException e){
      e.printStackTrace();
     }
     System.out.println(Thread.currentThread().getName()+"卖出一张,剩余票数"+(--this.ticket));
     }
    }
   }
 }
}


public class Thread01 {
 public static void main(String args[])
 {
  MyThread01 mt = new MyThread01();
  
  Thread t1 = new Thread(mt,"yi");
  Thread t2 = new Thread(mt,"er");
  Thread t3 = new Thread(mt,"san");
 
  t1.start();
  t2.start();
  t3.start();
 }

}


运行结果如下:
er卖出一张,剩余票数29
er卖出一张,剩余票数28
er卖出一张,剩余票数27
er卖出一张,剩余票数26
er卖出一张,剩余票数25
er卖出一张,剩余票数24
er卖出一张,剩余票数23
er卖出一张,剩余票数22
er卖出一张,剩余票数21
er卖出一张,剩余票数20
er卖出一张,剩余票数19
er卖出一张,剩余票数18
er卖出一张,剩余票数17
er卖出一张,剩余票数16
er卖出一张,剩余票数15
er卖出一张,剩余票数14
er卖出一张,剩余票数13
er卖出一张,剩余票数12
er卖出一张,剩余票数11
san卖出一张,剩余票数10
san卖出一张,剩余票数9
san卖出一张,剩余票数8
san卖出一张,剩余票数7
yi卖出一张,剩余票数6
yi卖出一张,剩余票数5
yi卖出一张,剩余票数4
san卖出一张,剩余票数3
san卖出一张,剩余票数2
san卖出一张,剩余票数1
er卖出一张,剩余票数0

数据符合逻辑要求。

后记:

多个线程共享同一个资源的时候,必须进行同步,但是过多的同步会造成系统的死锁

同步的关键字:synchronized

同步代码块中必须有一个需要同步的对象,一般都为当前对象 —— this。


posted on 2010-11-12 19:58 Soap MacTavish 阅读(183) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: