本帖最后由 imtoy 于 2012-03-18 00:08:46 编辑

解决方案 »

  1.   

    楼主的程序,为什么就出现单一线程在运行呢?
    或许是运行时间短的原因。理论上是三个线程都有机会运行的。但楼主程序的问题是,在同步方法里,虽然运行Thread.sleep(100),  但别的线程并不能在此时运行,因为这个同步对象的锁不释放。
    要象解决问题,很简单:把休眠放在同步方法的外边。
    public class TestSynchronized
    {
        public static void main(String[] args)
        {
            Ticket t = new Ticket();
            new Thread(t).start();
            new Thread(t).start();
            new Thread(t).start();
        }
    }class Ticket implements Runnable
    {
        int ticket = 100;
        String str = new String(""); //这个str用于同步目的。
        public void run()
        {
            while(true)
            {   
    try
    {
    Thread.sleep(100);
    }
             catch(Exception e)
    {
    e.printStackTrace(); // 最好加上.
    }
                 synchronized(str)
                 {
                     if(ticket > 0)
                     {
                    System.out.println(Thread.currentThread().getName() + "   :sales a ticket:" + ticket--);
                     }
                 }      if(ticket<=0) //票卖完让程序退出。
        break;
            }//end while
        }//end run
        
    }
      

  2.   

    我试过无数遍了,确实是只有第一个new出来的线程运行,很纳闷,就算是线程睡眠的时候其他线程不能运行,其他时间总能让别的线程运行吧?
      

  3.   

    其实,三个线程都启动了. 这个可以通过在run()方法里加一句:
       System.out.println("当前线程是:   "+Thread.currentThread().getName());
    看出来。
    我们看到的是进入同步方法里的线程,确实我们这样看到的结果是就一个总能进入同步方法里。这说明那两个线程总是不容易得到同步对象的锁,他们被阻塞在那个"Object's wait pool" 里,等那个同步对象锁,但总是不易得到。
    我在测试时,直接输出到屏幕上,看到的是一个线程在卖票。
    象下面的情况:
    其实,三个线程都启动了. 这个可以通过在run()方法里加一句:
       System.out.println("当前线程是:   "+Thread.currentThread().getName());
    看出来。
    我们看到的是进入同步方法里的线程,确实我们这样看到的结果是就一个总能进入同步方法里。说明那两个线程总是不容易得到同步对象的锁,他们被阻塞在那个"Object's wait pool" 里,等那个同步对象锁,还总是不易得到。
    我测试时,直接在屏幕输出,结果都是象这样:
    当前线程是:   Thread-0
    当前线程是:   Thread-2
    当前线程是:   Thread-1
    Thread-0   :sales a ticket:100
    Thread-0   :sales a ticket:99
    Thread-0   :sales a ticket:98
    ....
    ....
    ....
    Thread-0   :sales a ticket:3
    Thread-0   :sales a ticket:2
    Thread-0   :sales a ticket:1中间省略的都是一样.而如果我们把输出转向到一个文件,java csdn.thread.TestSynchronized>1.txt
    我们打开1.txt 时看到的是这样:
    当前线程是:   Thread-0
    当前线程是:   Thread-1
    当前线程是:   Thread-2
    Thread-0   :sales a ticket:100
    Thread-0   :sales a ticket:99
    Thread-0   :sales a ticket:98
    Thread-0   :sales a ticket:97
    Thread-2   :sales a ticket:96
    Thread-2   :sales a ticket:95
    Thread-2   :sales a ticket:94
    Thread-2   :sales a ticket:93
    Thread-2   :sales a ticket:92
    Thread-2   :sales a ticket:91
    Thread-2   :sales a ticket:90
    Thread-2   :sales a ticket:89
    Thread-2   :sales a ticket:88
    Thread-2   :sales a ticket:87
    Thread-2   :sales a ticket:86
    Thread-2   :sales a ticket:85
    Thread-2   :sales a ticket:84
    Thread-2   :sales a ticket:83
    Thread-2   :sales a ticket:82
    Thread-2   :sales a ticket:81
    Thread-1   :sales a ticket:80
    Thread-1   :sales a ticket:79
    Thread-1   :sales a ticket:78
    Thread-1   :sales a ticket:77
    Thread-1   :sales a ticket:76
    ...
    三个线程都能进入同步方法里了,我猜想可能的原因是: 在进入同步方法前尽量让线程有一段时间,能够让其他线程获得抢占(或被调度的机会).楼主自己试试看.
    ....