package tang.testthread;public class Demo1 implements Runnable{
Ticket window = new Ticket();
@Override
public synchronized void run() {

while(window.getCnt() > 0){
window.sell();
System.out.print(Thread.currentThread().getName() + " : ");
window.show();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) { Demo1 demo1 = new Demo1();
for(int i = 0;i<5;i++)
new Thread(demo1).start();
}
}class Ticket{
private int cnt = 100;

public void show(){
System.out.println(this.cnt);
}

public int getCnt(){
return this.cnt;
}

public  void sell(){
this.cnt--;
}
}
运行结果:Thread-0 : 99
Thread-0 : 98
Thread-0 : 97
Thread-0 : 96
Thread-0 : 95
Thread-0 : 94
Thread-0 : 93
Thread-0 : 92
Thread-0 : 91
Thread-0 : 90
Thread-0 : 89
Thread-0 : 88
Thread-0 : 87
Thread-0 : 86
Thread-0 : 85
Thread-0 : 84
Thread-0 : 83
Thread-0 : 82
Thread-0 : 81
Thread-0 : 80
Thread-0 : 79
Thread-0 : 78
Thread-0 : 77
Thread-0 : 76
Thread-0 : 75
Thread-0 : 74
Thread-0 : 73
Thread-0 : 72
Thread-0 : 71
Thread-0 : 70
Thread-0 : 69
Thread-0 : 68
Thread-0 : 67
Thread-0 : 66
Thread-0 : 65
Thread-0 : 64
Thread-0 : 63
Thread-0 : 62
Thread-0 : 61
Thread-0 : 60
Thread-0 : 59
Thread-0 : 58
Thread-0 : 57
Thread-0 : 56
Thread-0 : 55
Thread-0 : 54
Thread-0 : 53
Thread-0 : 52
Thread-0 : 51
Thread-0 : 50
Thread-0 : 49
Thread-0 : 48
Thread-0 : 47
Thread-0 : 46
Thread-0 : 45
Thread-0 : 44
Thread-0 : 43
Thread-0 : 42
Thread-0 : 41
Thread-0 : 40
Thread-0 : 39
Thread-0 : 38
Thread-0 : 37
Thread-0 : 36
Thread-0 : 35
Thread-0 : 34
Thread-0 : 33
Thread-0 : 32
Thread-0 : 31
Thread-0 : 30
Thread-0 : 29
Thread-0 : 28
Thread-0 : 27
Thread-0 : 26
Thread-0 : 25
Thread-0 : 24
Thread-0 : 23
Thread-0 : 22
Thread-0 : 21
Thread-0 : 20
Thread-0 : 19
Thread-0 : 18
Thread-0 : 17
Thread-0 : 16
Thread-0 : 15
Thread-0 : 14
Thread-0 : 13
Thread-0 : 12
Thread-0 : 11
Thread-0 : 10
Thread-0 : 9
Thread-0 : 8
Thread-0 : 7
Thread-0 : 6
Thread-0 : 5
Thread-0 : 4
Thread-0 : 3
Thread-0 : 2
Thread-0 : 1
Thread-0 : 0

解决方案 »

  1.   

    你都加了synchronized,每次肯定只能一个线程进去。而且sleep方法根本不会释放锁。
      

  2.   

    把Demo1 demo1 = new Demo1();放到for里面试试。
      

  3.   


    如果我想run里的while循环每执行一次都释放锁,该怎么做呢我不知道你能不能理解我的意图。我是想模拟买票过程,多窗口买票,这样的话,打印的结果中,票的数目应该是99到0的递减,而线程名则应该是随即的。
      

  4.   

    每次都释放锁就得用wait和notify。看看生产者消费者的列子,网上很多。
      

  5.   

    synchronized方法只能有一个线程能够进去,而这个线程进去之后将把从99到0都输出了~
      

  6.   

    关于楼主的问题,我今天刚好也研究这个,程序的意思差不多,只是没有使用sleep()。
    我使用的是同步代码块而不是同步方法,代码如下:
    package han;public class Tickets {
    int a=100;
    public static void main(String[] args) {
    new Tickets();

    }
    class MyThread implements Runnable{ @Override
    public void run() {
    // TODO Auto-generated method stub
    while(true){
       synchronized (this){
       if(a>0){
               System.out.println(a+"  "+Thread.currentThread().toString());
               a--;
           }
       else break;
    }
    }
    }
    }
    public Tickets(){
    MyThread tt=new MyThread();
    Thread t1=new Thread(tt);
    t1.setName("thread 1");
    Thread t2=new Thread(tt);
    t2.setName("thread 2");
    Thread t3=new Thread(tt);
    t3.setName("thread 3");
    t1.start();
    t2.start();
    t3.start();
    }

    }
    输出:
    100  Thread[thread 1,5,main]
    99  Thread[thread 1,5,main]
    98  Thread[thread 1,5,main]
    97  Thread[thread 2,5,main]
    96  Thread[thread 2,5,main]
    95  Thread[thread 2,5,main]
    94  Thread[thread 2,5,main]
    93  Thread[thread 2,5,main]
    92  Thread[thread 2,5,main]
    91  Thread[thread 2,5,main]
    90  Thread[thread 2,5,main]
    89  Thread[thread 2,5,main]
    88  Thread[thread 2,5,main]
    87  Thread[thread 2,5,main]
    86  Thread[thread 2,5,main]
    85  Thread[thread 2,5,main]
    84  Thread[thread 2,5,main]
    83  Thread[thread 2,5,main]
    82  Thread[thread 2,5,main]
    81  Thread[thread 2,5,main]
    80  Thread[thread 3,5,main]
    79  Thread[thread 1,5,main]
    78  Thread[thread 1,5,main]
    77  Thread[thread 3,5,main]
    76  Thread[thread 3,5,main]
    75  Thread[thread 3,5,main]
    74  Thread[thread 3,5,main]
    73  Thread[thread 3,5,main]
    72  Thread[thread 3,5,main]
    71  Thread[thread 3,5,main]
    70  Thread[thread 3,5,main]
    69  Thread[thread 3,5,main]
    68  Thread[thread 3,5,main]
    67  Thread[thread 3,5,main]
    66  Thread[thread 3,5,main]
    65  Thread[thread 3,5,main]
    64  Thread[thread 3,5,main]
    63  Thread[thread 3,5,main]
    62  Thread[thread 3,5,main]
    61  Thread[thread 3,5,main]
    60  Thread[thread 3,5,main]
    59  Thread[thread 3,5,main]
    58  Thread[thread 3,5,main]
    57  Thread[thread 3,5,main]
    56  Thread[thread 3,5,main]
    55  Thread[thread 3,5,main]
    54  Thread[thread 3,5,main]
    53  Thread[thread 3,5,main]
    52  Thread[thread 3,5,main]
    51  Thread[thread 3,5,main]
    50  Thread[thread 3,5,main]
    49  Thread[thread 3,5,main]
    48  Thread[thread 3,5,main]
    47  Thread[thread 3,5,main]
    46  Thread[thread 3,5,main]
    45  Thread[thread 3,5,main]
    44  Thread[thread 3,5,main]
    43  Thread[thread 3,5,main]
    42  Thread[thread 3,5,main]
    41  Thread[thread 3,5,main]
    40  Thread[thread 3,5,main]
    39  Thread[thread 3,5,main]
    38  Thread[thread 3,5,main]
    37  Thread[thread 3,5,main]
    36  Thread[thread 3,5,main]
    35  Thread[thread 3,5,main]
    34  Thread[thread 3,5,main]
    33  Thread[thread 3,5,main]
    32  Thread[thread 3,5,main]
    31  Thread[thread 3,5,main]
    30  Thread[thread 3,5,main]
    29  Thread[thread 3,5,main]
    28  Thread[thread 3,5,main]
    27  Thread[thread 3,5,main]
    26  Thread[thread 3,5,main]
    25  Thread[thread 3,5,main]
    24  Thread[thread 3,5,main]
    23  Thread[thread 3,5,main]
    22  Thread[thread 3,5,main]
    21  Thread[thread 3,5,main]
    20  Thread[thread 3,5,main]
    19  Thread[thread 3,5,main]
    18  Thread[thread 3,5,main]
    17  Thread[thread 3,5,main]
    16  Thread[thread 3,5,main]
    15  Thread[thread 3,5,main]
    14  Thread[thread 3,5,main]
    13  Thread[thread 3,5,main]
    12  Thread[thread 3,5,main]
    11  Thread[thread 3,5,main]
    10  Thread[thread 3,5,main]
    9  Thread[thread 3,5,main]
    8  Thread[thread 3,5,main]
    7  Thread[thread 3,5,main]
    6  Thread[thread 3,5,main]
    5  Thread[thread 3,5,main]
    4  Thread[thread 3,5,main]
    3  Thread[thread 3,5,main]
    2  Thread[thread 3,5,main]
    1  Thread[thread 3,5,main]
    我的目的达到了,但是也面临一个疑惑:synchronized (this)这个地方,我记得synchronized 后填任意一个对象都可以,但是我测试的时候只能填this,如写byte[] b=new byte[0],synchronized(b)就不能实现线程同步的效果。
    请高手指点啊~
      

  7.   


    synchronized 里要填写的是要同步的那个对象,不是随便写的
      

  8.   


    package Thread.day04;
    public class Demo1 implements Runnable{
    Ticket window = new Ticket();
    public synchronized void run() {

    while(window.getCnt() > 0){
    this.notify();
    window.sell();
    System.out.print(Thread.currentThread().getName() + " : ");
    window.show();
    try {
    this.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }

    }
    }

    public static void main(String[] args) { Demo1 demo1 = new Demo1();
    for(int i = 0;i<5;i++)
    new Thread(demo1).start();
    }
    }class Ticket{
    private int cnt = 100;

    public void show(){
    System.out.println(this.cnt);
    }

    public int getCnt(){
    return this.cnt;
    }

    public  void sell(){
    this.cnt--;
    }
    }
      

  9.   

    synchronized run锁的是run方法论并且第一个进程进来后会一直持有,只有锁ticket对象才能达到你的要求。
      

  10.   

    实质锁定的是Demo1的引用,也可在Demo1 内部 Object o = new Object(),对其进行上锁。
      

  11.   

    run()方法被锁定了,而又没有某种方法能够释放该锁 所以资源就被某一个线程抢光了,但是,也不是每一次运行都是Thread-0吧
      

  12.   

    改了楼主的部分代码,楼主参考一下:
    public class Demo1 implements Runnable{
        Ticket window = new Ticket();
        @Override
        public void run(){  
            while(window.getCnt()>0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //卖票单独用一同步方法处理.
                //
                sell();
            }//end while.
        }
        //卖票方法.这是同步的.一旦卖完,马上退出同步,让其他线程得到机会.
        //
        public synchronized void sell(){
            if(window.getCnt()>0){
                System.out.print(Thread.currentThread().getName() + " is selling  : ");
                window.show();                     //这里显式的正是本线程要卖的票.
                window.sell();                     //这个相当于总票数减一.
            }//end if.
        }    //---------- main()    
        public static void main(String[] args) {
            Demo1 demo1 = new Demo1();
            for(int i = 0;i<5;i++)
            new Thread(demo1).start();
        }//end main.
    }
     
    class Ticket{
        private int cnt = 100;
         
        public void show(){
            System.out.println(this.cnt);
        }
         
        public int getCnt(){
            return this.cnt;
        }
         
        public void sell(){
            this.cnt--;
        }
    }
      

  13.   

    五个线程都执行了,只是最先先执行的线程把所有的票都卖光了,其他线程都没有票卖了。所以没有看到其他线程的打印信息。你把Thread.currentThread().getName()放在run方法的第一行,就会看到每个线程都执行了。
      

  14.   

    这位老兄的讲解比较有深度啊,但见群主没啥反应,担心会让群主看不到,帖子沉下去,还专程找我们过来帮忙顶贴,gan兄的执着的热心真可谓感天动地啊,我觉得楼主,要认真看看、好好看看啊!