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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 张忠豹 中级黑马   /  2012-8-15 16:13  /  1389 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

package exception;
class Ticket implements Runnable{
private int ticketCount =400;//假定有400张票
@Override
//这个错在什么地方?
/*
public void run() {
  for(int i=ticketCount;i>0;i--){
   System.out.println(Thread.currentThread().getName()+"卖"+i+"号票");
  }
}*/
//这一种,与下面的差不多。为什么第二种运行时,结果有重复的值。错在什么地方?
/*
public void run(){
  for(;ticketCount>0;ticketCount--){
   System.out.println(Thread.currentThread().getName()+"卖"+ticketCount+"号票");
  }
}
*/

public void run(){
  while(ticketCount>0){
   
    System.out.println(Thread.currentThread().getName()+"卖"+ticketCount--+"号票");
   
  }
}
}
public class SaleTicket {
public static void main(String args[]){
  Ticket ticket = new Ticket();
  Thread thread1 = new Thread(ticket),
    thread2 = new Thread(ticket),
    thread3 = new Thread(ticket),
    thread4 = new Thread(ticket);
  thread1.start();
  thread2.start();
  thread3.start();
  thread4.start();
}
}

3 个回复

倒序浏览
第一种全局属性ticketCount没有变化,也就是每个线程定义一个i,各自运行400次,一共1600次

第二种,在for循环判断语句中,ticketCount>0;ticketCount--,但是进程不一定马上执行,可能有多条进程同时判断,那么就造成打印出相同的票,并且总数量也不是400,可能是401 402 403

第三种,for循环只判断ticketCount,而没有改变全局变量,只有在进程运行,出票时,icketCount--,所以相对是线程安全的.只运行400次
回复 使用道具 举报
public void run()
{
  for(int i=ticketCount;i>0;i--)
    System.out.println(Thread.currentThread().getName()+"卖"+i+"号票");
}
如果用了这种方法,楼主可以仔细观察一下,结果不是简单的重复,而是每个重复值都会出现4次,变成了每个线程都要卖400张票。
原因是每个线程开启后,因为ticketCount把值赋给了i,关键就是这个i,它是在run方法中创建的,所以不是4个线程的共用数据,每个线程的i都是从400开始的,而且彼此之间还相互不影响,所以就造成了重复的结果。

public void run(){
  for(;ticketCount>0;ticketCount--){
   System.out.println(Thread.currentThread().getName()+"卖"+ticketCount+"号票");
  }
}
循环中用的是ticketCount,它是共享数据,所以不存在重复的情况。
回复 使用道具 举报
集思广益还是有效果的。都能指出一些问题。不过第三种的确有问题。需要用到线程同步的玩意……
问题已解决
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马