public class TrainTicketSell 
{
    public static int ticket=100;
    public static void main(String args[])
    {
        new Sell().start();
        new Sell().start();
        new Sell().start();
        new Sell().start();
    }
}
class Sell extends Thread
{
    public static String str=new String ("");
    public void run()
    {
       synchronized(str)
       {
             while(TrainTicketSell.ticket>0)
                 System.out.println(Thread.currentThread().getName()+":"+TrainTicketSell.ticket--);
       }
    }
}
//不知道为什么只有一个线程在运行呀

解决方案 »

  1.   

    public static String str=new String ("");
    synchronized(str)明白了吗?
      

  2.   

    str是static的, 也就是你所有Sell线程共有的.
    第一个线程拿了他的锁,在没执行完之前是不会放这个锁的,那么其他线程都要等着.
    等他执行完了,ticket也变0了,其他线程自然什么也不打印了
    你在while之前随便加点打印语句看看.
      

  3.   

    //例程:模拟四个售票点发售总共100张车票,一个售票点用一个线程。
    //extends Thread方法
    //implements Runnable方法
    //关键:多个线程要去处理同一资源,同一个资源只能对应同一个对象。
    //总结:使用Runnable接口适合于多个相同程序代码的线程去处理同一资源的情况,
    //把虚拟CPU(线程)同程序的代码、数据(实现了Runnable接口的类)有效分离,
    //体现了面向对象的设计思想。
    //思考:如果实在想用extends Thread的方法创建4个线程卖同100张票呢?public class 习题10_线程应用_ThreadDemo
    {
    public static void main(String [] args)
    {
    ThreadTest t=new ThreadTest();
    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();
    }
    }
    class ThreadTest implements Runnable
    {
    private int tickets=100;
    public void run()
    {
    while(tickets>0)
    {
    System.out.println(Thread.currentThread().getName()
    + " is saling ticket "  + tickets--);
    }
    }

    /*
     *可见,实现Runnable 接口相对于继承Thread类来说,有如下显著的好处:
    1、适合多个相同程序代码的线程去处理同一资源的情况,把线程同程序的代码、
    数据有效分离,较好地体现了面向对象的设计思想。
    2、可以避免由于Java的单继承特性带来的局限。我们经常碰到这样一种情况,
    即当我们要将已经继承了某一个类的子类放入多线程中,
    由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,
    那么,这个类就只能采用实现Runnable接口的方式了。
     */
      

  4.   

    这个20分不容易拿到啊
    synchronized就是异步
    线程只能一个一个进入资源的临界区,一个推出后,另一个才能进入
      

  5.   

    ticket=100,这个数值设置的大一点,可能会看到结果。
      

  6.   

    楼上几位说的没错,关键就在public static String str=new String ("");上,你把static去掉看看结果
      

  7.   

    你写的代码有问题,你run方法中的代码的同步块,还有一个循环语句,也就是说第一个进程进入这个同步块,要把所有的票售出能才退出这个同步块。当别的进程访问这个块时,因为没有票了,也打印不出数据来了。把run方法中的代码改成下面就可以了
    while(true) {
           synchronized(str)
           {
                 if(TrainTicketSell.ticket>0)
                     System.out.println(Thread.currentThread().getName()+":"+TrainTicketSell.ticket--);
                 else
                  break;
           }
           try {
        Thread.sleep(10);
        } catch (InterruptedException e) {
        e.printStackTrace();
        }
          }这样四个进程都能打印相应的数据
      

  8.   

    楼上的观点是对的!只要将我的源程序少改一处四个线程都可以运行!这20分本应该给你,可是有三位高手说"楼上几位说的没错,关键就在public static String str=new String ("");上"那么请各位给出实例并讲出原由来,下面是我根据楼上的观点修改的:程序运行正常(四个线程都在运行)
    public class TrainTicketSell 
    {
        public static int ticket=100;
        public  static  String str=new String ("");
        public static void main(String args[])
        {
            new Sell().start();
            new Sell().start();
            new Sell().start();
            new Sell().start();
        }
    }
    class Sell extends Thread
    {
        public void run()
        {
           while(TrainTicketSell.ticket>0)
           {
               synchronized(TrainTicketSell.str)
               {
                    //while(TrainTicketSell.ticket>0)
                         System.out.println(Thread.currentThread().getName()+":"+TrainTicketSell.ticket--);
               }
           }
        }
    }
      

  9.   

    你把public static String str=new String ("");改成public String str=new String ("");就不能保证进程的同步了,因为str为一个成员变量,这时,每个进程都有一把锁str,这时str就达不到互斥的作用。下面这代码是修改你的代码后,能把0打印出来,说明把str设为成员变量,达不到进程同步
    public class TrainTicketSell 
    {
        public static int ticket=100;
        public static void main(String args[])
        {
            new Sell().start();
            new Sell().start();
            new Sell().start();
            new Sell().start();
        }
    }
    class Sell extends Thread
    {
        public String str=new String ("");
        public void run()
        {
           synchronized(str)
           {
                 while(TrainTicketSell.ticket>0) {
                  TrainTicketSell.ticket--;
                     System.out.println(Thread.currentThread().getName()+":"+TrainTicketSell.ticket);
                     try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
                 }
           }
        }
    }
    如果你想用把str改成成员变量,则你可以实现Runnable接口,这样也可以达到进程的同步
      

  10.   

    上面代码错了
    public class TrainTicketSell 
    {
        public static int ticket=100;
        public static void main(String args[])
        {
            new Sell().start();
            new Sell().start();
            new Sell().start();
            new Sell().start();
        }
    }
    class Sell extends Thread
    {
        public String str=new String ("");
        public void run()
        {
           synchronized(str)
           {
                 while(TrainTicketSell.ticket>0) {
                  TrainTicketSell.ticket--;
                  
                     System.out.println(Thread.currentThread().getName()+":"+TrainTicketSell.ticket);
                     try {
       Thread.sleep(100);
       } catch (InterruptedException e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
       }
                     
                 }
           }
        }
    }
    这能打印出很多4个零
      

  11.   

    不好意思,两次发的代码一个样,再发一次,楼主不介意吧
    这时打印出来的结果是96 95 ....0 0 0 0
    public class TrainTicketSell 
    {
        public static int ticket=100;
        public static void main(String args[])
        {
            new Sell().start();
            new Sell().start();
            new Sell().start();
            new Sell().start();
        }
    }
    class Sell extends Thread
    {
        public String str=new String ("");
        public void run()
        {
           synchronized(str)
           {
                 while(TrainTicketSell.ticket>0) {
                  TrainTicketSell.ticket--;
                  try {
        Thread.sleep(100);
        } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
                     System.out.println(Thread.currentThread().getName()+":"+TrainTicketSell.ticket);
                     
                     
                 }
           }
        }
    }
      

  12.   

    本人自学JAVA,以下是个人的理解synchronized 是线程的同步 ,目的 是使得线程1次只能有一个得以运行有2种方法 
    1 是使用 有 synchronized标记 的方法
    public synchronized void 方法名(){ 
    }2 像你一样 使用synchronized(str)  锁定  线程共有的一个对象 str
    就可以达到同步
      

  13.   

    手太慢了~~~~  看到楼主的主贴,发现只要把while从 同步中放到同步前就可以实现楼主的目的、、、、、、、看下去发现已经、、、、、、、、、、、、、、、、