有没有更好的方法来重新启动 Java 线程?

huangapple go评论76阅读模式
英文:

Is there any better way to restart java threads?

问题

  1. 有没有更好的方法来重新启动线程?

  2. 经常调用 Thread.isAlive() 方法是否合适?

  3. 如果不合适,你能为此提供其他解决方案吗?

class AllActions {
    LinkedBlockingQueue<String> action1list = new LinkedBlockingQueue<>();
    LinkedBlockingQueue<String> action2list = new LinkedBlockingQueue<>();
    LinkedBlockingQueue<String> action3list = new LinkedBlockingQueue<>();

    doActions(List<String> actions) {
        action1list.addAll(actions);

        Thread action1Thread = new Thread(this::doAction1);
        Thread action2Thread = new Thread(this::doAction2);
        Thread action3Thread = new Thread(this::doAction3);

        do {
            if (!action1list.isEmpty() && !action1Thread.isAlive()) {
                action1Thread = new Thread(this::doAction1);
                action1Thread.start();
            }

            if (!action2list.isEmpty() && !action2Thread.isAlive()) {
                action2Thread = new Thread(this::doAction2);
                action2Thread.start();
            }
            
            if (!action3list.isEmpty() && !action3Thread.isAlive()) {
                action3Thread = new Thread(this::doAction3);
                action3Thread.start();
            }
        } while (/* 所有列表都有内容,且任何线程仍存活 */)
    }

    doAction1() {
        action1list.take();
        /* 一些操作 */
        action2list.put();
    }
    /* 其他操作 */
}
英文:

1)Is there any better way to restart threads?

2)Is it ok to call Thread.isAlive() so often?

3)If not, can you advise the other solution for this?

class AllActions{
    LinkedBlockingQueue&lt;String&gt; action1list = new LinkedBlockingQueue&lt;&gt;();
    LinkedBlockingQueue&lt;String&gt; action2list = new LinkedBlockingQueue&lt;&gt;();
    LinkedBlockingQueue&lt;String&gt; action3list = new LinkedBlockingQueue&lt;&gt;();

    doActions(List&lt;String&gt; actions){

    action1list.addAll(actions);

    Thread action1Thread = new Thread(this::doAction1);
    Thread action2Thread = new Thread(this::doAction2);
    Thread action3Thread = new Thread(this::doAction3);
    
        do{
            if (!action1list.isEmpty() &amp;&amp; !action1Thread.isAlive()) {
                    action1Thread = new Thread(this::doAction1);
                    action1Thread.start();
                }
 
            if (!action2list.isEmpty() &amp;&amp; !action2Thread.isAlive()) {
                    action2Thread = new Thread(this::doAction2);
                    action2Thread.start();
                }
            if (!action3list.isEmpty() &amp;&amp; !action3Thread.isAlive()) {
                    action3Thread = new Thread(this::doAction3);
                    action3Thread.start();
                }
        }while( /*All lists have something and any thread is alive */)
}

    doAction1(){
        action1list.take()
        /* some things */
        action2list.put()
    }
    /* Other actions */

答案1

得分: 5

你无法“重新启动”一个Java线程。一旦线程终止,就无法重新启动。

但这不是你正在做的事情。实际上,你正在重复创建和启动(而不是重新启动)_新的_线程。这是低效的,因为线程的启动和退出代价相当大。另外,“主”线程正在轮询其他线程,以查看它们是否仍然存活,这是另一个低效之处。

绝对有一种更好的方法。

看看ExecutorService API。它允许你将无限数量的“任务”提交到工作队列,并有一组线程来处理它们。该API负责启动工作线程,传递任务,并在它们崩溃时重新启动。执行器服务可以使用固定大小的线程池实例化,可以使用缩放和增长的池,可以使用无限或有界的工作队列等。

获取更多信息,请从这里的javadoc这里的Oracle教程开始。

英文:

You can't "restart" a Java thread. Once it has terminated, it cannot be restarted.

But that's not what you are doing. What you are actually doing is repeatedly creating and starting (not restarting) new threads. That is inefficient because thread start and exit are rather expensive. In addition, the "main" thread is polling the other threads to see if they are still alive, which is another inefficiency.

There definitely is a better way.

Look at the ExecutorService API. It allows you to submit an indefinite number of "tasks" to a work queue and have a pool of threads process them. The API takes care of starting the worker threads, passing them tasks, and restarting if they crash. Executor services can be instantiated with fixed size pools, pools that shrink and grow, infinite of bounded work queues, and so on.

For more information; start with the javadoc and the Oracle tutorials on this topic.

huangapple
  • 本文由 发表于 2020年4月5日 15:38:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/61039460.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定