import java.awt.*;
import java.util.*;public class SimpleThread extends Thread {
  private int countDown = 5;
  private int threadNumber;
  private static int threadCount = 0;
  public SimpleThread() {
    threadNumber = ++threadCount;
    System.out.println("Making " + threadNumber);
  }
  public void run() {
    method1();
    method2();
    try {
           sleep(1000);
         } catch (InterruptedException e){}    while(true) {
      System.out.println("Thread " +
        threadNumber + "(" + countDown + ")");
      if(--countDown == 0) return;
    }
  }
  public synchronized void method1(){
    System.out.println("aaaaaaaaaaaaaaaaaaa");    System.out.println("bbbbbbbbbbbbbbbbbbbbb");
  }
  public synchronized void method2(){
  System.out.println("cccccccccccccc");  System.out.println("ddddddddddddd");
}
  public static void main(String[] args) {
    for(int i = 0; i < 5; i++)
      new SimpleThread().start();
    System.out.println("All Threads Started");
  }
}用JBUILDER运行的结果是:
Making 1
Making 2
Making 3
aaaaaaaaaaaaaaaaaaa  //public synchronized void method1()一个线程调用改方法应该会把“a”和“b“连续打印出来,还没运行完,怎么会被另外一个线程抢占在下一行中打印”a“呢?
aaaaaaaaaaaaaaaaaaa
All Threads Started
bbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbb
cccccccccccccc   //两个synchronized方法怎么会交替运行呢??
aaaaaaaaaaaaaaaaaaa
cccccccccccccc
ddddddddddddd
bbbbbbbbbbbbbbbbbbbbb
ddddddddddddd
cccccccccccccc
ddddddddddddd
Thread 2(3)
Thread 2(2)
Thread 2(1)
Thread 3(3)
Thread 3(2)
Thread 3(1)
Thread 1(3)
Thread 1(2)
Thread 1(1)

解决方案 »

  1.   

    结果第四行://public synchronized void method1()一个线程调用改方法应该会把“a”和“b“连续打印出来,还没运行完,怎么会被另外一个线程抢占在下一行中打印”a“呢?
      

  2.   

    多线程时CPU到底怎么调度,那是谁也不知道的事情,其中充满随机性。
    不说你这是两句语句,就算是 一句  ++threadCount  也可能执行到一般时被中断。要想中间不中断,加锁就行了,不过要注意不要导致死锁。
      

  3.   

    你的这多个线程是不同的对象,你的锁加在那些对象上,不同的线程获得不同的锁,当然会出问题。
    你申明一个 byte [] mutex = new byte[0]; 再在方法里面对 mutex加锁,就ok了。
      

  4.   

    呵呵……很简单,也很有迷惑性。因为你的方法在不同的实例里面,所以不存在争夺问题。你每次都new了一个新的Thread来执行,自然是各自执行各自了,没有争执,也就没有什么需要同步的问题。
    加锁也只能控制大家来抢同一个东西的情况,你这里每个实例有自己的方法,大家不争不抢,自然加锁不起作用,也就可能被别人打断。如果把method1和method2改成static,就可以实现你想要的效果了。或者,前面只new一个SimpleThread,后面循环这么写
    SimpleThread t = new SimpleThread(); 
    for (int i = 0; i < 5; i++) {
        new Thread(t).start(); 
    }
    不过,这样做的话,你的构造函数就要重新考虑了,否则就会死循环了。
    (为了给你测试,我的机器都死了一回了…… T_T 给分做个补偿吧)
      

  5.   

    呵呵,谢谢有点感觉了
    没有改构造函数,为什么会死循环呢??
    Making 1
    All Threads Started
    aaaaaaaaaaaaaaaaaaaThread-0
    bbbbbbbbbbbbbbbbbbbbbThread-0
    ccccccccccccccThread-0
    dddddddddddddThread-0
    Thread 1(3)
    Thread 1(2)
    aaaaaaaaaaaaaaaaaaaThread-0
    Thread 1(1)
    bbbbbbbbbbbbbbbbbbbbbThread-0
    aaaaaaaaaaaaaaaaaaaThread-0
    bbbbbbbbbbbbbbbbbbbbbThread-0
    aaaaaaaaaaaaaaaaaaaThread-0
    bbbbbbbbbbbbbbbbbbbbbThread-0
    aaaaaaaaaaaaaaaaaaaThread-0
    bbbbbbbbbbbbbbbbbbbbbThread-0
    ccccccccccccccThread-
    dddddddddddddThread-0
    Thread 1(0)
    Thread 1(-1)
    Thread 1(-2)
    Thread 1(-3)

    程序里面
        while(true) {
          System.out.println("Thread " +
            threadNumber + "(" + countDown + ")");
          if(--countDown == 0) return;
        }
    当countDown=0时不就返回了吗?怎么会出现负数?迷惑
      

  6.   

    改成<=0吧。因为只有那个恰好把countDown变成0的线程会停止。其他的因为再进行减法就变成负数了,所以继续运行。我就是这样死的…… T_T下次一定把代码看全了再跑!