java多线程售票程序实例及synchronized理解

开始学习java编程,遇到到了线程同步的问题。在网上查找资料,根据网上的讲解自己调试代码。有如下心得,写下来和众多正在学习java的同学分享。文中对java同步操作的有些观点尚欠准确,有哪些错误的地方,感谢各位java大牛的批评指正。

代码如下:

public class MultiThreadDemo{
public static void main(String[] args) { 
  TxtThread tt = new TxtThread(); 

  new Thread(tt).start(); 
  new Thread(tt).start(); 
  new Thread(tt).start(); 
  new Thread(tt).start(); 

}

class TxtThread implements Runnable { 
Integer num = 100; // 共100张票,有4个线程共同来进行出售

public void run() { 
while(num>0){       ---------------------------      1
synchronized (num) { 
try {       ---------------------------       2
     if(num >0){ ---------------------------       3
     System.out.println(Thread.currentThread().getName() 
     + "this is " + num--);         ----------------------------- 4

}

//Thread.sleep(10); 
    } catch (Exception e) { 
   e.getMessage(); 
   
   
  }

}

程序解析

1.共有4个线程A,B,C,D同时对记录剩余票数的变量num进行操作。

2.当B线程正在执行时,运行到标记1处时,对当前剩余的票数进行判断;若还有票,获得对num变量访问的锁,进入同步代码段。其他三个线程将会被阻塞在标记1处。(同步代码段并不表示临界区,当某个正在执行同步代码段的线程,也可能被调度器切换出去,让其他的线程占用CPU)

3.判断num的值是否大于0,即是否还有票,注意此次判断很重要,原因下面的解释。

注意

标记3中的if判断很重要,最开始在学习他人的代码时,对在同步代码段中,进行如标记3出的判断觉得很好奇。明明在标记1处进行了判断,当进入同步代码段后,num变量只能被当前线程所访问,那么,num的值一定会大于0了,为什么还要判断了。基于这样的想法,没有进行标记3处的判断,结果程序运行后,num的值出现了0,-1,-2这样三个结果。后来反思后,认为可能是因为,可能是,当进行标记1处的判断后,线程B就可能被调度器给切换出去了(多线程中,当前线程可能在任何地方被切换出去,不能对被切换出去的地点进行任何假设)。注意,此种情况下,线程B还没有获得num的锁。此时,若线程D开始被执行,线程D执行标记1处的判断,然后,在获得num的锁,接着执行同步代码,对num的值进行了修改。在之后的某个时间,线程B又开始被执行了,此时,线程B的执行从标记1之后开始执行,不在进行标记1出的判断了,然后在标记4出,再次对num进行了访问,此次的访问和标记1处的访问不同,两次的num的值不同,标记4中访问的值为线程D访问完的,num可能已经为0或-1了。然后,再不进行判断的情况下,自减后,就会造成num值出现0,-1,-2的现象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值