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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lcjasas 中级黑马   /  2013-4-2 07:36  /  2306 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 lcjasas 于 2013-4-3 19:03 编辑

class Ticket implements Runnable
{
private int tick = 100;
Object obj = new Object();
public void run(){
  while(true){
   synchronized(obj){
    if(tick>0){
      try { Thread.sleep(10); }   catch (Exception e){}
     System.out.println(Thread.currentThread().getName()+"-----sale:  "+tick--);
    }
   }
  }
}
}
class  TicketDemo2
{
public static void main(String[] args)
{
  Ticket t = new Ticket();
  Thread t1 = new Thread(t);//创建了一个线程
  Thread t2 = new Thread(t);
  Thread t3 = new Thread(t);
  Thread t4 = new Thread(t);
  t1.start();
  t2.start();
  t3.start();
  t4.start();
}
}
疑问。。。   
try { Thread.sleep(10); }   catch (Exception e){}
这样的结果是多个线程抢夺执行权,谁抢到执行谁。
try { Thread.sleep(10); }   catch (Exception e){}  
多了一个封号,也能编译成功,但是似乎只开启了最先抢到执行权的线程,为什么啊。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

10 个回复

倒序浏览
try { Thread.sleep(10); }   catch (Exception e){}  ;//这个";"号加没加对程序本身是没有影响的

//多了一个封号,也能编译成功,但是似乎只开启了最先抢到执行权的线程,为什么啊 ----->这个在你加没加";"都有可能出现
public void run(){
  while(true){
   synchronized(obj){  //假如t1获得锁,t1执行一次之后锁已释放掉,重新回到外层的while循环,其它在等待的线程就有机会获取到执行权,具体情况不同机器运行结果不同吧
    if(tick>0){
      try { Thread.sleep(10); }   catch (Exception e){}
     System.out.println(Thread.currentThread().getName()+"-----sale:  "+tick--);
    }
   }
  }
}
//这是我的理解.希望对你有所帮助,

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
“;”分号 只是语句结束标识 ,没有任何影响,你说的那种情况,可以通过改变 tick = 500 来观察一下,多次运行比较之后,就会发现其他线程也可以执行

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
try { Thread.sleep(10); }   catch (Exception e){}  ;这里多了一个分号,其实对代码没什么影响,并不是分号的原因,这个就是抢夺执行权,很有可能thread-0能抢到全部的执行权,而楼主只要多运行几次,估计就会出现不是全部thread-0的情况了。加不加分号都有可能出现这种情况。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
分号无影响, 当前线程持有 锁。 try { Thread.sleep(10); }   catch (Exception e){}  只是让当前线程sleep 10毫秒。 只有其释放锁后其他线程测能获得执行权

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
那个";"是语句结束符,对程序没影响的、、

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
那个";"只是一句空语句,对程序没有影响。
synchronized(obj){  
    if(tick>0){
      try { Thread.sleep(10); }   catch (Exception e){}
     System.out.println(Thread.currentThread().getName()+"-----sale:  "+tick--);
    }
   }

每个线程在执行锁块中的语句其他线程就可以拿到执行权了。
如果把tick值变成更大效果更明显,当然多核处理器的计算机效果会尤为明显。
不像单核处理器只是分出时间片段,不是真正的同时执行多个线程。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
分号不分号的没什么区别,我只能说你多试几次,要不就把数据变大点,变大了,多运行一段时间,别的就会进来了

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
若还有问题,继续追问; 没有的话,将帖子分类改成【已解决】哦~
回复 使用道具 举报
try { Thread.sleep(10); }   catch (Exception e){};
加不加“;”是没有影响的,你的那种情况是执行权分配的问题,如果让程序多执行几次就会看到不同的执行顺序。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
首先,解释为什么多了个分号也会编译通过: 因为分号只是代表一条语句,如果只写了一个分号,相当于写了个空语句;catch{}后面是没有分号的,如果加了分号就相当于在它后面写了句空语句,所以,写多少分号都是没有影响的。
其次,回答你“似乎只开启了最先抢到执行权的线程”的疑问:这几个线程优先级是相等的,看cpu随即分配了,谁先抢到锁谁先执行,当一个线程执行完一次if语句后会重新返回while条件判断,和其他的线程抢锁。但不论顺序如何每个线程都是有机会被执行到的。我做过实验了。由于是随机的,每次执行的结果都是不同的,你要多试验几次。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马