a499538194 2012-11-16 16:32
浏览 214
已采纳

线程暂停的问题

我的主线程启动了一个线程a,a的run里面就是一个死循环不停的向控制台输出。
现在比如主线程是一个用户界面,点击界面的暂停按钮,a就不再输出,点继续接着输出.
用a.wait()在a的run方法执行完之前获取不到线程a对象的锁,但是a的run就是一个死循环,他永远执行不完.

其实真实情况是这样,a的run里面运行的是一段很费时的代码,想随时可以暂停他,也可以继续执行

  • 写回答

1条回答 默认 最新

  • blogzhoubo 2012-11-17 10:07
    关注

    可能是因为你的子线程的run方法里面有synchronized(this),run方法一直运行,所以一直没有释放对子线程对象的锁,主线程里面当然获取不到。

    即使在主线程中能得到锁,调用子线程对象的wait()方法只能使主线程自身处于等待状态,并不会停止子线程,只有在子线程的run方法里面调用wait()才能让子线程暂定运行,所以你这么做是不行的。

    [b]可行的做法是:
    1.在子线程对象里面加一个runFlag,run方法运行的时候,每循环一次就检查一下这个runFlag,根据runFlag的状态决定是暂定,还是继续执行,还是退出。

    2.主线程里面根据需要去设置子线程对象中的runFlag。

    3.暂定的时候,直接更新runFlag即可。
    继续运行的时候,更新完runFlag后,还需要调用notify()来通知子线程来解除子线程的wait状态。(因为此时子线程处于wait状态,无法判断runFlag的状态)[/b]

    具体可以参照下面的代码:

    屏幕输入s,代表暂停子线程的运行。
    屏幕输入c,代表子线程继续运行。
    屏幕输入e, 代表结束子线程和主线程。

    因为主线程和子线程共用同一个console,所以屏幕输出会有些混乱,不过不影响功能。

    [code="java"]class SubThread extends Thread{
    private int runFlag=1;

    public void doStop(){
    runFlag = 2;
    }

    public void doContinue(){
    runFlag = 1;
    }

    public void doExit(){
    runFlag = 0;
    }

    public void run(){
    while(runFlag != 0){
    if(runFlag == 1){
    System.out.println("sub thread is running...");
    }else if(runFlag == 2){
    synchronized(this){
    System.out.println("sub thread is waiting...");
    try{
    this.wait();
    System.out.println("sub thread continue...");
    }catch (Exception e)

    {
    e.printStackTrace();
    }
    }

    }
    try{
    sleep(1000);
    }catch (Exception e)

    {
    e.printStackTrace();
    }

    }
    System.out.println("sub thread is over");
    }
    }

    public class MainThread
    {
    public static void main(String[] args)
    {
    SubThread sthread = new SubThread();
    sthread.start();

        byte[] b = new byte[10];
        String str = "";
    
        while(true){
          try{
            Thread.sleep(100);
          }catch(Exception e){
            e.printStackTrace();
          }
    
          System.out.print("please input:");
          try{
            System.in.read(b);
          }catch(Exception e){
            e.printStackTrace();
          }
    
          str = new String(b);
          System.out.println(str);
          if(str.startsWith("s")){
            sthread.doStop();
          }else if(str.startsWith("c")){
            sthread.doContinue();
            synchronized(sthread){
              sthread.notify();
            }
          }else if(str.startsWith("e")){
            sthread.doExit();
            synchronized(sthread){
              sthread.notify();
            }
            break;
          }
        }
        System.out.println("main thread is over");
    }
    

    }[/code]

    如果把主线程改成GUI画面的话,那么点击按钮的时候可能需要点击多次,才能获得响应,因为主线程和子线程分时复用CPU资源,你点击按钮的时候,如果GUI主线程此时没有获得时间片,那么可能不会检测到你的点击动作。多点几次肯定就能获得响应。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 nslt的可用模型,或者其他可以进行推理的现有模型
  • ¥15 arduino上连sim900a实现连接mqtt服务器
  • ¥15 vncviewer7.0安装后如何正确注册License许可证,激活使用
  • ¥15 phython如何实现以下功能?查找同一用户名的消费金额合并2
  • ¥66 关于人体营养与饮食规划的线性规划模型
  • ¥15 基于深度学习的快递面单识别系统
  • ¥15 Multisim仿真设计地铁到站提醒电路
  • ¥15 怎么用一个500W电源给5台60W的电脑供电
  • ¥15 请推荐一个轻量级规则引擎,配合流程引擎使用,规则引擎负责判断出符合规则的流程引擎模板id
  • ¥15 Excel表只有年月怎么计算年龄