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 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?