public class TestThread01 {
public static void main(String args[]) {
MyThread mt1 = new MyThread(); Thread t1 = new Thread(mt1);
Thread t2 = new Thread(mt1);
t1.start();
t2.start(); }}class MyThread implements Runnable {
int ticket = 20; public void run() {
synchronized (this) {
for (int i = 0; i < 25; i--) {
if (ticket > 0) {
System.out.println(Thread.currentThread().getName() + " "
+ ticket);
ticket--; }
}
}
}
}

解决方案 »

  1.   

    synchronized 
    看看这个关键字
      

  2.   

    但是有点书上,直接就说实现runnable,用Thread就可以实现资料共享
    如果ticket写在system.out里面的话,下面就可以共享,为什么 ????
    class TestThread01
    {
    public static void main(String args[])
    {
    MyThread mt1 = new MyThread();

    Thread t1 = new Thread(mt1);
    Thread t2 = new Thread(mt1);
    t1.start();
    t2.start();



    }}class MyThread implements Runnable
    {
    int ticket = 20;
    public void run(){

    for( int i=0; i <25  ; i--)
    {
    if(ticket > 0)
    {
    System.out.println(Thread.currentThread().getName()+" "+ticket--);


    }
    }
    }
      

  3.   

     MyThread mt1 = new MyThread();
            Thread t1 = new Thread(mt1);
            Thread t2 = new Thread(mt1);因为你只new 了一次Runnalbe接口,数据都是从这一个里面取,
     你想要的结果应该是这样的,  
       static  int ticket = 20;
     MyThread mt1 = new MyThread();
            Thread t1 = new Thread(mt1); MyThread mt2= new MyThread();
            Thread t2 = new Thread(mt2);
      

  4.   

    多加了几个线程,一样可以实现。书上就是说runnable优点,可以实现资料共享。但是把ticket--,写在system.out外面就不可以了,为什么 
    class TestThread01
    {
    public static void main(String args[])
    {
    MyThread mt1 = new MyThread();

    new Thread(mt1).start();
    new Thread(mt1).start();
    new Thread(mt1).start();
    new Thread(mt1).start();
    new Thread(mt1).start();
    new Thread(mt1).start();
    new Thread(mt1).start();
    new Thread(mt1).start();



    }}class MyThread implements Runnable
    {
    int ticket = 20;
    public void run(){

    for( int i=0; i <25  ; i--)
    {
    if(ticket > 0)
    {
    System.out.println(Thread.currentThread().getName()+" "+ticket--);


    }
    }
    }
    }
    Thread-0 20
    Thread-0 17
    Thread-2 18
    Thread-2 12
    Thread-1 19
    Thread-1 9
    Thread-2 10
    Thread-6 11
    Thread-5 13
    Thread-0 14
    Thread-4 15
    Thread-3 16
    Thread-4 2
    Thread-0 3
    Thread-5 4
    Thread-6 5
    Thread-2 6
    Thread-1 7
    Thread-7 8
    Thread-3 1
      

  5.   

    这个有一定概率的,让线程sleep看的就比较明显,也可以多运行几次,肯定会看到有重复的
      

  6.   

    楼主,你的代码实际是两个线程同时去读写一个对象,而在多线程处理时又没有加上线程同步机制。
    所以就存在读写的时候出现一些脏数据。
    以下是我执行两次的结果//第一次
    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-1 20//第二次
    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-1 11
    Thread-1 9
    Thread-0 10
    Thread-0 7
    Thread-1 8
    Thread-1 5
    Thread-1 4
    Thread-1 3
    Thread-0 6
    Thread-1 2
    Thread-0 1//第三次
    Thread-0 20
    Thread-1 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-1 10
    Thread-0 10
    Thread-0 8
    Thread-0 7
    Thread-1 9
    Thread-1 5
    Thread-1 4
    Thread-1 3
    Thread-0 6
    Thread-1 2
    Thread-0 1从结果可以看出来,每次运行结果都会出现重复的几个数据,第一次是20重复,第二次是11重复,第三次是20和10重复。
    重复n次执行数据就是20+n。
    出现这种情况是因为两个线程都去读写一个数据,当线程1读写完线程2再去读写时不会出现重复。但是如果线程1执行完读还未执行写时执行权让给了线程2,那么线程2读到的就是同一个数。
    以第一次结果为例:
    程序启动时,两个线程同时读取到了20。
    但是接下来线程运行权全部被线程1抢占,于是出现了线程1连续输出了接下来的数据。
    最后线程2抢占了运行权进行了控制台输出了最开始他读到的20 。如果改成System.out.println(Thread.currentThread().getName()+" "+ticket--);。由于读写放在一条指令执行,就避免了输出重复数据。Thread-0 20
    Thread-0 19
    Thread-0 18
    Thread-0 17
    Thread-0 16
    Thread-0 15
    Thread-1 14
    Thread-0 13
    Thread-0 11
    Thread-1 12
    Thread-0 10
    Thread-0 8
    Thread-0 7
    Thread-0 6
    Thread-0 5
    Thread-1 9
    Thread-0 4
    Thread-1 3
    Thread-1 1
    Thread-0 2
    如果改成线程同步,那么就不存在两个线程同时去读写一个数据。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
      

  7.   

    那意思说Runnable确实实现资料共享,但是如果读写在不在一条指令上,也会出现脏读。
      

  8.   

    首先for (int i = 0; i < 25; i--) 这是一个死循环啊其次我没理解你说的“共享资料”是什么意思?两个线程操作的是同一块同存:MyThread -> ticket,先把这块内存的数值输出,再把它减一,所以,两个线程的输出一定是像结果显示的那样没有任何规律可言,输出重复的,或输出间断的,都是合理的,楼主对其中的哪一个输出不理解?