/*代码原意是Game线程每隔0.3秒钟给int变量head加一,然后打印出来;TimeCounter线程在第1.5秒钟使Game线程等待3秒钟,然后Game线程重新运行,可是我的程序在运行时候Game线程并没有等待3秒钟,为什么呢?*/
 
class TimeCounter extends Thread { Game game; TimeCounter(Game g) {
game = g;
} public void run() {
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (game != null)
game.stop();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (game != null)
game.resume();
}
}
class Game implements Runnable {
// 只写重要的代码 int head; Thread thread; public void run() { while (true) {
head++;
System.out.println(head);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} public void start() {
thread = new Thread(this);
thread.start();
} public void stop() {
try {
thread.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} public void resume() {
thread.notify();
} public static void main(String[] args) { Game game = new Game();
TimeCounter tc = new TimeCounter(game);
game.start();
tc.start();
}
}

解决方案 »

  1.   

    在TimeCounter线程中调用了game.stop()无形中是要让TimeCounter线程wait可在Game类线程的运行模块中设置
                if (isStopped) {
                    try {
                        synchronized (thread) {
                            thread.wait();
                        }
                    }
                    catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                } stop方法中
         public void stop() {
            isStopped = true;
        }resume方法中
         public void resume() {
            synchronized(thread){
                thread.notify();
                isStopped = false;
            }
        }
    其余不变
      

  2.   

    在一个线程里是不能直接控制另外一个线程的运行状态,你只能通过设置状态标志的方式来间接控制。class TimeCounter extends Thread
    {    Game game;    TimeCounter(Game g)
        {
            game = g;
        }    public void run()
        {
            try
            {
                Thread.sleep(1500);
            }
            catch(InterruptedException ex)
            {
                ex.printStackTrace();
            }
            if(game != null)
            {
                game.setStop(true);
            }
        }
    }class Game implements Runnable
    {
    //   只写重要的代码    int head;
        boolean stop;
        Thread thread;    public void run()
        {
            while(true)
            {
                synchronized(this)
                {
                    head++;
                    System.out.println(head);                try
                    {
                        if(stop)
                        {
                            this.wait(3000);
                            stop = false;
                        }
                        Thread.sleep(300);
                    }
                    catch(InterruptedException ex)
                    {
                        ex.printStackTrace();
                    }
                }
            }
        }    public void start()
        {
            thread = new Thread(this);
            thread.start();
        }    public void setStop(boolean stop)
        {
            this.stop = stop;
        }    public static void main(String[] args)
        {
            Game game = new Game();
            TimeCounter tc = new TimeCounter(game);
            game.start();
            tc.start();
        }
    }
      

  3.   

    出现了Sleep了,说明你的代码需要重新设计。
      

  4.   

    偶不知道让一个线程Wait或者Sleep能体现什么功力 
      

  5.   

    为什么说 有sleep就不是好程序。
    比如:若程序需要 类似“脉冲”或“心跳” 的功能时,就要这样。
      

  6.   

    调用wait和notify前必须获得对象的同步锁。 synchronized (obj){
        obj.wait(); //这里释放同步锁
    }
      

  7.   

    healer_kx ,
    出现了Sleep了,说明你的代码需要重新设计。
    那用什么办法让线程休息呢?
      

  8.   

    哈哈,这个问题相当有意思,而且很典型!绕了一回才弄清楚怎么回事!
    至于LZ的程序直接跑肯定有异常,因为wait方法要释放所有锁资源,所以它的调用前提是必须先获得对象锁资源,我修改了一下代码,可以跑了,不过现象很有趣,大家可以看看为什么会这样运行?是否知道真正的原因呢?
    class TimeCounter extends Thread   { 
    private Game game;  public TimeCounter(Game g){ 
    game = g; 
    }  public void run(){
    try{
    System.out.println("Counter waiting...");
    Thread.sleep(1500);
    }catch(InterruptedException e){
    e.printStackTrace();
    }
    System.out.println("stop begin...");
    if(game != null)
    game.stop();

    System.out.println("3000 begin...");
    try{
    Thread.sleep(3000);
    }catch(InterruptedException e){
    e.printStackTrace();
    }

    if(game != null) 
    game.resume(); 
    }
    } public class Game implements Runnable{ 
    private int head; 

    public void run(){ 
    while(true){ 
    head++; 
    System.out.println("Head:"+head); 
    try{ 
    Thread.sleep(300); 
    }catch(InterruptedException e){  
    e.printStackTrace(); 


    }  public void start(){
    new Thread(this).start();
    }

    public synchronized void stop(){ 
    try{ 
    System.out.println("waiting...");
    this.wait(); 
    }catch(InterruptedException e){  
    e.printStackTrace(); 

    }  public void resume(){ 
    System.out.println("notify...");
    notify(); 


    public static void main(String[] args){ 
    Game game = new Game(); 
    TimeCounter tc = new TimeCounter(game); 
    game.start();
    tc.start(); 

    } //打印结果
    Head:1
    Counter waiting...
    Head:2
    Head:3
    Head:4
    Head:5
    stop begin...
    waiting...
    Head:6
    Head:7
    Head:8
    Head:9
    Head:10
    Head:11
    Head:12
    Head:13
    Head:14
    ...一直Head下去了
    稍后我公布答案哦……确实需要很多Java线程知识!
      

  9.   

    我们让CPU给线程分配了时间片,就是让它在那睡觉或者等待嘛?SO KIND OF YOU.
      

  10.   

    我CPU双核,跑线程经常出错。。很多程序单核CPU跑出来的和我的CPU跑出来的结果不一致。
      

  11.   

    10楼的程序 在运行到this.wait();时把线程TimeCounter停在那里了 因为没别的线程执行notify() 所以这线程一直等下去了而这个线程 new Thread(this).start();  一直执行下去10楼想说的是不是:
    this.wait(); 这里停的并非 new Thread(this).start();  这里产生的线程但这好像不是楼主提出的问题吧
      

  12.   

    to 2楼:你说的“在一个线程里是不能直接控制另外一个线程的运行状态,你只能通过设置状态标志的方式来间接控制”我有一个疑问,因为在一个线程中控制另外的线程在j2se 1.4中是可以通过主控线程 调用被控线程的suspend()和resume()方法很轻易地实现,现在这两个方法被j2se5 给deprecated了,但是肯定存在相应的方法来弥补原来suspend()和resume()方法的功能,尽管这些方法是自己写的
      

  13.   

    另外我把你修改后程序的黑体字如下给删除后程序也可以正常运行啊
    class   Game   implements   Runnable 

    //       只写重要的代码         int   head; 
            boolean   stop; 
            Thread   thread;         public   void   run() 
            { 
                    while(true) 
                    { 
                            synchronized(this) 
      

  14.   

    呵呵,13楼的大概说了个所以然,不过我想告诉大家的是线程和对象是两回事。每个Object都有wait,notify等线程方法,所以我见过很多人都分不清楚线程和对象,这里其实只有TimeCounter和Game对象,没有什么TimeCounter线程和Game线程,程序确实启动了两个线程,暂且叫做T1和T2,对象只是线程可以访问的内存资源,这两个线程都可以访问TimeCounter和Game对象,那么对象拥有的wait,nofity等线程方法又做何解释呢?它们的含义是影响到访问此对象资源的线程所以在Game中this.wait停止的不是什么Game线程,因为Game只是对象,是内存资源,它停止的是当时访问Game的线程对象(T1和T2中的一个)
    然后就像13楼说的,那个线程假设是T1停了,而再没有被唤醒过……希望大家好好理解线程这个东东,呵呵!