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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘佳 中级黑马   /  2012-8-14 10:22  /  2437 人查看  /  10 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 刘佳 于 2012-8-14 10:46 编辑
  1. class Ticket implements Runnable
  2. {
  3.         private int tick = 100;
  4.         Object obj = new Object();
  5.         boolean flag = true;
  6.         public void run()
  7.         {
  8.                 if (flag)
  9.                 {
  10.                         while (true)
  11.                         {
  12.                                 synchronized(obj)
  13.                                 {
  14.                                         if (tick>0)
  15.                                         {
  16.                                                 try{Thread.sleep(10);}catch(Exception e){}
  17.                                                 System.out.println(Thread.currentThread().getName()+"....code:"+tick--);
  18.                                         }
  19.                                 }
  20.                         }
  21.                 }
  22.                 else
  23.                         while (true)
  24.                         {
  25.                                 show();
  26.                         }
  27.         }
  28.         public synchronized void show()
  29.         {
  30.                 if (tick>0)
  31.                 {
  32.                         try{Thread.sleep(10);}catch(Exception e){}
  33.                         System.out.println(Thread.currentThread().getName()+"....show....:"+tick--);
  34.                 }
  35.         }
  36. }

  37. class ThisLockDemo
  38. {
  39.         public static void main(String[] args)
  40.         {
  41.                 Ticket t = new Ticket();  
  42.                 Thread t1 = new Thread(t);
  43.                 Thread t2 = new Thread(t);
  44.                 t1.start();
  45.                 t.flag = false;
  46.                 t2.start();
  47.         }
  48. <font color="red">}</font>
复制代码
上面的是完整的程序代码,该代码中主线程先运行完后,t1,t2两个线程才开始运行。
主线程和多线程不是交替的执行吗,那为何上面代码诠释的含义不同呢?



class ThisLockDemo
{
public static void main(String[] args)
{
  Ticket t = new Ticket();   
  Thread t1 = new Thread(t);
  Thread t2 = new Thread(t);
  t1.start();
  /*
t1.start()此时为临时状态,一定要等到主线程结束以后才能获得运行资格?
主线程和多线程不能同时交替执行吗?
*/

  t.flag = false;
  t2.start();
}
}


评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

10 个回复

倒序浏览
  1. class ThisLockDemo
  2. {
  3. public static void main(String[] args)
  4. {
  5.   Ticket t = new Ticket();   
  6.   Thread t1 = new Thread(t);
  7.   Thread t2 = new Thread(t);
  8.   t1.start();
  9.   /*此时为临时状态,不是非要等到主线程结束以后才能获得运行资格。
  10. 主线程和多线程就是同时交替执行的。
  11. 注意:Java中的多线程是一种抢占机制而不是分时机制。抢占机制指的是有多个线程处于可运行状态,但是只允许一个线程在运行,他们通过竞争的方式抢占CPU。
  12. */
  13.   t.flag = false;
  14.   t2.start();
  15. }
  16. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
周瑞 发表于 2012-8-14 10:33

那为何毕老师讲的这个程序,要等主线程运行完了,t1和t2两个线程才能开始运行呢?
回复 使用道具 举报
class ThisLockDemo
{
public static void main(String[] args)
{
  Ticket t = new Ticket();   
  Thread t1 = new Thread(t);
  Thread t2 = new Thread(t);
  t1.start();
  /*
t1.start()此时为临时状态,一定要等到主线程结束以后才能获得运行资格?
主线程和多线程不能同时交替执行吗?
*/                        //此时的t1线程为就绪状态,等待cpu给它分配执行权,一旦拿到执行权,它就会启动进入运行状态,同时会和主线程竞争cpu的执行权
                        //因此不会等到主线程结束再执行,t1线程实际上就是和主线程交替执行
  t.flag = false;
  t2.start();
}
}

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 黑马_许芸 于 2012-8-14 11:04 编辑

那为何毕老师讲的这个程序,要等主线程运行完了,t1和t2两个线程才能开始运行呢?
         
回复 使用道具 举报
本帖最后由 焦晨光 于 2012-8-14 11:11 编辑

根据主函数中的代码,主线程在创建完两个线程对象后,又做了什么?
启动线程t1 ,给t对象的flag变量赋值,启动t2线程
ok 主线程结束
主线程在创建完子线程后就做了两件事,分别启动两个子线程
然后就结束
没有后续代码
如果主函数中再来一个100的循环
你就能看到 主线程和子线程会交替运行


主函数中的代码,被主线程一扫而过
主线程结束后释放cpu执行权,然后t1和t2开始竞争cpu执行权

但也有这种可能(这种可能几乎为0)主线程启动t1线程后,t1线程立马得到执行权
但是t1线程 非常努力的 通过了各种判断后,顺利进入run方法的循环体开始执行
但是,刚进入就(Thread.sleep(10);)睡趴那了(释放了执行权)
于是主线程很郁闷的有得到了执行权,接着把t2线程启动,恍惚间,主线程立马就被t2线程抢占了执行权(此时的主线程已经结束)
紧接着t2线程气势汹汹的杀入run方法,跋山涉水,好不容易得走进主循环,立马又(Thread.sleep(10);)睡趴了。
(释放了执行权)
主线程在启动玩t2后就已经非常遗憾的结束了
等t1和t2睡醒。。。。主线程已经沉没了。。。

评分

参与人数 1技术分 +1 收起 理由
张_涛 + 1 赞一个!

查看全部评分

回复 使用道具 举报
刘佳 中级黑马 2012-8-14 11:24:21
7#
焦晨光 发表于 2012-8-14 10:56
根据主函数中的代码,主线程在创建完两个线程对象后,又做了什么?
启动线程t1 ,给t对象的flag变量赋值, ...

根据该程序分析,无论将循环设置的多大,都是主线程先执行完,然后t1和t2两个线程才开始交替执行。
结果中所有的都在执行show方法,也证明了该程序并不是主线程和子线程在交替的运行!!!
回复 使用道具 举报
刘佳 发表于 2012-8-14 11:24
根据该程序分析,无论将循环设置的多大,都是主线程先执行完,然后t1和t2两个线程才开始交替执行。
结果 ...


你主函数的循环是放在了t1和t2线程启动语句后面吗?
回复 使用道具 举报
刘佳 中级黑马 2012-8-14 11:43:28
9#
焦晨光 发表于 2012-8-14 11:31
你主函数的循环是放在了t1和t2线程启动语句后面吗?

就上面那个程序
回复 使用道具 举报
刘佳 发表于 2012-8-14 11:43
就上面那个程序

class ThisLockDemo
{
        public static void main(String[] args)
        {
                Ticket t = new Ticket();  
                Thread t1 = new Thread(t);
                Thread t2 = new Thread(t);
                t1.start();
                t.flag = false;
                t2.start();
  for(int i=0;i<=100;i++)
  {
   System.out.println(Thread.currentThread().getName()+"main");
  }
        }
把这个for循环添加进去看看。
回复 使用道具 举报
焦晨光 发表于 2012-8-14 11:47
class ThisLockDemo
{
        public static void main(String[] args)

晕,哥儿们,这有区别吗
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马