A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

package day11.thread;
/**
* 简单的售票程序。多个窗口同时售票。
* 注意给所有线程公共的数据tick用static修饰。
* 注意安全问题:使用Thread.sleep()可以有效检查。tick有同一张或者0、-1号等问题。
* 为什么会多次出现同一张呢?????
* 原因:多条语句操作同一个线程共享的数据时,一个线程对多条语句只执行了一部分。此时另一个线程参与进来执行。
* 解决方案:同步代码块。
* 同步的前提:两个以上的线程;多个线程使用同一个锁。
* @author Administrator
*
*/
public class ThreadDemo3 {
public static void main(String[] args) {
  Ticket t1 = new Ticket();
  Ticket t2 = new Ticket();
  Ticket t3 = new Ticket();
  
  t1.start();
  t2.start();
  t3.start();
}
}
class Ticket extends Thread {

// private static Object obj = new Object();
private static int tick = 100;

public void run() {
  while(true) {
//   synchronized(obj) {
    if(tick > 0) {
     try {
      Thread.sleep(10);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     System.out.println(this.getName() + " sale: " + tick--);
    }
//   }
  }
}
}

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

5 个回复

倒序浏览
楼主,你想问什么?
回复 使用道具 举报
下边是我一次运行时输出的一段结果:100号票居然被卖了3次,
98号票被卖了两次。
Thread-0 sale: 100
Thread-2 sale: 100
Thread-1 sale: 100
Thread-2 sale: 99
Thread-0 sale: 98
Thread-1 sale: 98
回复 使用道具 举报
我只能说lz可以继续往下看视频。。。我估计楼主的意思是为什么不加同步多线程会出现重复。
简单解释一下就是cpu运行机制,cpu在某一个固定的瞬间只运行一个线程,有多个线程时cpu快速切换“速度可以用刷刷刷形容。。”但是你的多线程共同操作的代码并不是一句话就完事的,而是好几句话,可能线程1还没读完那个共同操作的代码线程2就开始读共同代码了。就是说没有加锁就不能保证一个线程把共同使用的代码块一次性读完,就会导致出现重复的情况。。。有点罗嗦了,但是希望楼主能明白

评分

参与人数 1技术分 +1 收起 理由
田磊阳 + 1

查看全部评分

回复 使用道具 举报
hubby 发表于 2013-11-21 08:55
我只能说lz可以继续往下看视频。。。我估计楼主的意思是为什么不加同步多线程会出现重复。
简单解释一下就 ...

我不知道将System.out.println(this.getName() + " sale: " + tick--);
拆成tick--;System.out.println(this.getName() + " sale: " + tick);
会有什么不同效果。就说这目前没有拆开的情况,虽然有多个线程异步执行,也就是他们可能都打印100号票,但是打完之后tick应该--多次啊,那就不应该再打印99号票了。也不是说绝对没有,例如t1和t2都将打印100号票了,t1先打印并执行到要打印下一张即99号票。然后此时应该就有多次打印100号票接着还打印99号票的情况。但是发现这里不会出现没有打印的票,即我说的两次打印100号,可能就不再打印99号票的情况。因为--两次,所以下一次应该直接打印98号票。
回复 使用道具 举报
首先楼主你的代码中你把同步注释掉了,因此出现了多次卖出100号的情况。

代码一:System.out.println(this.getName() + " sale: " + tick--);

代码二:tick--;System.out.println(this.getName() + " sale: " + tick);

然后我跟你讲下我对以上代码一和代码二的理解吧:

假如tick的值是100,

代码一是:先把tick=100打印,再--变成tick=99留给下一次用;

代码二是:tick本来是100的,但是先--变成99了,然后打印的tick当然就是99了。

评分

参与人数 1技术分 +1 收起 理由
黄炳期 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马