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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马振鹏 中级黑马   /  2012-7-12 17:44  /  1520 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class ThreadDemo {
        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);
            t1.start();
            t2.start();
            t3.start();
               
        }

}
class Ticket implements Runnable{
       
        public void run(){
       
                int sumTicket = 1000;
                Object obj = new Object();
                while(true){
                        if(sumTicket>0){
                                synchronized (obj) {
                                try {
                                        Thread.sleep(10);
                                } catch (InterruptedException e) {                                       
                                        e.printStackTrace();
                                }
                                System.out.println(Thread.currentThread().getName()+" sale -....."+sumTicket--);
                                }
                         }
                  }
                }
}

把共享数据放到run()中,在执行,是三个进程一起执行,但是效果为什么顺序执行?而没有发生线程交替错开的情况呢?

3 个回复

倒序浏览
你这个程序无论怎么运行 都是打印出顺序执行的效果
因为无论哪个线程拿到锁后都不会释放锁 这又是个死循环程序 线程在里面即便sleep了也照样握着锁不放
除非你把 Thread.sleep(10)改成obj.wait(10)才能实现你期望的效果
wait():释放资源,释放锁
sleep():释放资源,不释放锁,这是Thread类的方法
回复 使用道具 举报
本帖最后由 RWJ2012 于 2012-7-12 20:20 编辑
  1. public class ThreadDemo {
  2.         public static void main(String[] args) {
  3.                 Ticket t = new Ticket();
  4.                 Thread t1 = new Thread(t);
  5.                 Thread t2 = new Thread(t);
  6.                 Thread t3 = new Thread(t);
  7.                 t1.start();
  8.                 t2.start();
  9.                 t3.start();

  10.         }

  11. }

  12. class Ticket implements Runnable {
  13.         Object obj = new Object(); //此同步锁对象只能有一份,否则不能实现同步效果。
  14.          int sumTicket = 1000;//总共有1000张票,要做为票(Ticket)的类成员变量,不能在run方法中声明。
  15.         public void run() {           
  16.                 while (true) {
  17.                               //try....catch语句块要放在同步语句块外面,这样才能够让其它两个线程有机会执行,获得CPU时间片。
  18.                          try {
  19.                                 Thread.sleep(10);
  20.                         } catch (InterruptedException e) {
  21.                                 e.printStackTrace();
  22.                         }
  23.                         synchronized (obj) {
  24.                         //if()判断要放在同步语句块内,当sumTicket=0时,其它线程访问时,有可能条件满足,又将sumTicket值减1,使某一线程取到的票号为-1。
  25.                         if (sumTicket > 0) {
  26.                                         System.out.println(Thread.currentThread().getName()
  27.                                                         + " sale -....." + (--sumTicket));
  28.                          } else {
  29.                                 break;
  30.                         }
  31.                         }
  32.                 }
  33.         }
  34. }
复制代码
上面的程序实现了楼主所想要的功能。楼主代码中出现的线程顺序执行的问题是由于将Thread.sleep(10)语句放在synchronized语句块中,导致某一线程执行时,其它线程得不到执行的机会。
回复 使用道具 举报
本帖最后由 徐然 于 2012-7-12 20:20 编辑

你这个程序里面没有共享数据啊
你把int sumTicket = 1000;
定义在局部位置,然后每个线程进来,都读一次int sumTicket = 1000;
就是说每个线程都有自己的sumTicket ,他们各自操作自己的,互不影响
如果你把int sumTicket = 1000定义在成员位置,就行了
但是这样打印出来的结果会出现
Thread-2 sale -.....-1
Thread-0 sale -.....0
所以要把if语句也放进同步代码块中
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马