如何使用标志重新启动线程中的操作?

时间:2016-12-30 22:21:29

标签: java multithreading

我尝试使用volatile布尔值作为一个标志来停止/启动/重新启动线程中的操作,但它不起作用。它只是永远持续下去,永远不会终止。任何有关如何正确执行此操作或为何我的代码不起作用的帮助将不胜感激。提前谢谢。

public class thread {

    public static int i = 0;
    private static Thread print = null;
    private static printThread runnable = null;

    public static void main(String[] args) {
        runnable = new printThread();
        print = new Thread (runnable);
        print.start();

        System.out.println("Starting");
        runnable.begin();
        if(i > 5)
        {
            runnable.terminate();
        }

        i = 10;
        runnable.begin();
        if(i > 15)
        {
            runnable.terminate();
        }
    }

    public static final void print()
    {
        System.out.println(i);
        i++;
    }

    public static final class printThread implements Runnable {
        private volatile boolean running = false;

        public void terminate() {
            running = false;
        }

        public void begin() {
            running = true;
        }

        public boolean isRunning() {
            return running;
        }

        public void run() {
            while(true)
            {
                if(running)
                {
                    print();
                }

                else
                {

                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

在你的代码中while循环执行永远不会结束。您可以引入2个状态:终止并等待模拟线程开始/暂停/重启/停止。但是,即使你暂停Thread它将会运行,只是不同的代码分支将在while循环中执行。

请参阅下面的代码段

public static final class printThread implements Runnable {
    private volatile boolean waiting = false;
    private volatile boolean terminated = false;


    public void terminate() {
        terminated = true;
    }

    public void pause() {
        waiting = true;
    }

    public void restart() {
        waiting = false;
    }

    public void run() {
        while(!terminated) {
            if(waiting) {
                //the thread is paused
            } else {
                //the thread is running
            }
        }
    }
}

答案 1 :(得分:1)

  

然而它不起作用。它只是永远持续下去,永远不会终止。

在您线索的run()方法中,您不会注意volatile boolean running字段的值。它可能应该是这样的:

    public void run() {
        while(!running) {
            print();
            // you might want a short Thread.sleep(10); here to stop the spinning
        }
    }

然而,正如@Anton指出的那样,一旦你的线程终止,它就不能在没有其他标志的情况下重新启动。看他的答案。

此外,您在主线程和打印线程之间共享i。这也需要volatile,以便可以正确共享。由于您要在多个线程中递增它,因此您应该使用AtomicInteger

 public static AtomicInteger i = new AtomicInteger();
 ...
 if (i.get() > 5) ...
 ...
 i.set(10);
 ...
 i.incrementAndGet();

其他几条评论:

  • 注意static字段。 printrunnable应仅在main(...)方法内定义以限制访问。
  • 类应以大写字母开头,因此它应为PrintThread
  • 实际上,因为PrintThread不是一个主题,它应该是PrintRunnable,或者甚至更好,Printer