如何启动,暂停和恢复我的线程? (通过扩展类中的线程)

时间:2013-08-04 02:57:24

标签: java multithreading

基本上,我想要做的是启动所有线程,暂停所有线程,然后使用多线程方法恢复所有线程。我只是想找到一个简单的解决方案。我不确定我是否必须使用计时器或什么。现在,当我运行它时,线程就像是以随机顺序执行(我想PC只是随机选择它想要在某个时间运行的那些)。

class ChoppingThread extends Thread
{
    public void run()
    {
        for(int j=40;j!=0;j-=10)
            System.out.println("Chopping vegetables...("+j+" seconds left)");
    }   
 }
class MixingThread extends Thread
{
    public void run()
    {
        for(int k=60;k!=0;k-=10)
            System.out.println("Mixing sauces...("+k+" seconds left)");
    }
}
class TenderizingThread extends Thread
{
    public void run()
    {
        for(int j=50;j!=0;j-=10)
            System.out.println("Tenderizing meat...("+j+" seconds left)");
    }
}
class MultiThreadTasking
{
    public static void main (String [] args)
    {
        ChoppingThread ct = new ChoppingThread();
        MixingThread mt = new MixingThread();
        TenderizingThread tt = new TenderizingThread();

        System.out.println("\nWelcome to the busy kitchen.");
        //putting threads into ready state
        ct.start();
        mt.start();
        tt.start();
    }
}

3 个答案:

答案 0 :(得分:2)

要协调它们,请使用CyclicBarrier

要同时启动它们,请使用CountDownLatch

谷歌上面的两个类有很多例子和解释。

要完全了解正在发生的事情,请阅读Java Concurrency In Practice book

答案 1 :(得分:2)

可能还有其他方法可以达到相同的效果,但这是我能想到的最简单的方法(我知道,可悲的不是它)......

基本上,这是一个特殊的Runnable,具有一些额外的管理功能。

这基本上包含一个状态标志,指示任务的状态和监视器锁

public class ThreadFun {

  public static void main(String[] args) {
    MyTask task = new MyTask();
    Thread thread = new Thread(task);
    thread.start();
    try {
      Thread.sleep(1000);
    } catch (InterruptedException ex) {
    }
    task.pauseTask();
    try {
      Thread.sleep(1000);
    } catch (InterruptedException ex) {
    }
    task.resumeTask();
    try {
      Thread.sleep(1000);
    } catch (InterruptedException ex) {
    }
    task.stopTask();
  }

  public enum TaskState {

    Running,
    Stopped,
    Paused

  }

  public static class MyTask implements Runnable {

    private static final Object PAUSED_LOCK = new Object();

    private volatile TaskState state = TaskState.Running;

    public void pauseTask() {
      if (state == TaskState.Running) {
        System.out.println("Paused...");
        state = TaskState.Paused;
      }
    }

    public void resumeTask() {
      if (state == TaskState.Paused) {
        state = TaskState.Running;
        synchronized (PAUSED_LOCK) {
          PAUSED_LOCK.notifyAll();
        }
        System.out.println("Resumed...");
      }
    }

    public void stopTask() {
      if (state == TaskState.Running || state == TaskState.Paused) {
        state = TaskState.Stopped;
        System.out.println("Stopped...");
      }
    }

    public boolean isStopped() {
      return state == TaskState.Stopped;
    }

    public boolean isPaused() {
      return state == TaskState.Paused;
    }

    protected void doPause() {
      synchronized (PAUSED_LOCK) {
        while (isPaused()) {
          try {
            PAUSED_LOCK.wait();
          } catch (InterruptedException ex) {
          }
        }
      }
    }

    @Override
    public void run() {

      int index = 0;
      while (!isStopped() && index < 1000) {
        try {
          Thread.sleep(25);
        } catch (InterruptedException ex) {
        }
        doPause();
        index++;
        System.out.println(index);
      }
      stopTask(); // Make sure the task is marked as begin stopped ;)

    }

  }
}

主要标准是您需要在适当的位置汇集isStoppeddoPause,以确保它们根据需要开始实施......

答案 2 :(得分:0)

我相信您可以使用Object.waitThread.interrupt完成此操作。

Object.wait阻止,直到notify被调用。所以

private boolean paused;
private Object waitObject;
...
public void run() {
    for ... {
        if (this.paused) { this.waitObject.wait(); }
    ...

public void pause() { this.paused = true; }
public void resume() { this.paused = false; this.waitObject.notify(); }

然后你可以调用pause来暂停线程。

Thread.interrupt有助于停止。

private boolean paused;
...
public void run() {
    for ... {
        // interrupted() is different from interrupt()!
        if (this.iterrupted()) { break; }
    ...

要停止它,你可以从另一个线程调用interrupt()

这是基本的想法,但这里有很多细节需要担心。例如,wait可以抛出您需要处理的InterruptedException。此外,wait不保证仅在notify之后返回。 可以随机返回。这是一对教程: