gpt4 book ai didi

java - 有关Executors.newSingleThreadExecutor()的问题

转载 作者:行者123 更新时间:2023-12-03 12:48:25 27 4
gpt4 key购买 nike

这是有关以下代码的程序流程的问题:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {
public static void main(String args[]) {
ExecutorService service = null;
try {
service = Executors.newSingleThreadExecutor();

System.out.println("begin");
service.execute(() -> System.out.println("Printing zoo inventory"));
service.execute(() -> {
for(int i = 0; i< 3; i++)
System.out.println("Printing record: " + i);
});
service.execute(() -> System.out.println("printing zoo inventory"));
} finally {
if(service != null)
service.shutdown();
}
}
}
在上面的代码中,一旦我们与“System.out.println(“begin”)交叉,...线程执行器便依次执行以下每个 Action 任务(基本上是Runnable lambda)。
我的理解是,考虑线程执行程序“服务”的执行,这些“任务”(sop(“打印...”),for循环,sop(“打印..”))将一个接一个地运行。线程执行程序上的每个Runnable lambda。
我是否正确,除非Runnable lambda在当前行完成,否则程序流将不会移至下一行?例如,除非Runnable lambda完成s.o.p(“打印动物园库存”)...否则,它不会在下一行启动下一个Runnable lambda吗?
如果当前的线程执行器行带有计算密集型的Runnable lambda,那么在什么情况下会发生什么情况?在这种情况下,下一行(如果它包含另一个Runnable lambda)..将必须等到当前线程执行程序完成该任务后再执行?

最佳答案

Q & A-“我是否正确,除非无法完成的lambda在当前行完成,否则程序流将不会移至下一行?例如,除非Runnable lambda完成对sop(“printing zoo stock”)的操作,否则它将不会启动下一行的下一个Runnable lambda?”
-是的,您是正确的。 *
-“如果当前线程执行器行带有计算密集型的Runnable lambda,在这种情况下会发生什么情况?
下一行(如果它包含另一个Runnable lambda)..将不得不
等到当前线程执行器完成任务?”
-是的,它必须等待。 *
-“你最爱的颜色?”
-红色
(*)假设您要检查ExecutorService中的行为,将等式中的主线程(及其执行某些操作的调用)排除在等式之外,然后重点关注池工作线程。主线程独立运行,某些实现可能会在决定时向其分配任务,这就是本注释的原因。
Test & Compare我将尝试将此执行器与多线程执行器进行比较,以显示两种方法之间的差异。
关于您的问题(关注阻塞等待的情况),给出的答案会根据所使用的执行程序服务而完全不同。使用第二个选项,答案将是:

  • 如果有一个工作人员,它将能够移动到下一行,即使当前行没有完成。
  • 不,如果线程可用,则不必等待。
  • 红色。
  • SingleThreadExecutor

    Creates an Executor that uses a single worker thread operating off anunbounded queue.Tasks areguaranteed to execute sequentially, and no more than one task will beactive at any given time.


    您在池上只有一个线程,因此所有任务都分配给它。如文档所述,它必须按顺序执行它们。要进行一个简单的测试,例如:
    service = Executors.newSingleThreadExecutor();

    service.execute(() -> System.out.println("Printing zoo inventory"));
    service.execute(() -> {
    try {Thread.sleep(5000); System.out.println("Woke up"); }
    catch (InterruptedException e) {e.printStackTrace();}
    });
    service.execute(() -> System.out.println("Finish"));
    输出
      Printing zoo inventory     // ---- [Thread 1] 
    //...5s
    Woke up // ---- [Thread 1]
    Finish // ---- [Thread 1] -{x}-
    如以下至少平时的时间图所示:
       {task1}    {task2}                          {task3}
    ^ ^ ^
    | | (~5s) |
    [Thread1]-->[Thread1]---------------------->[Thread1]->{x}
    对其进行调试,唯一可用的线程确认它是执行前两个任务的线程。图片示例来自原始OP的问题:
    enter image description here
    第三项任务的断点-已完成两项
    enter image description here

    MultiThreaded Pool
    使用 FixedThreadPool作为示例。当一个以上的工作线程可用时,进程的行为就会改变;对于此示例,设置了两个线程。
    与往常一样,应仔细阅读文档:
    enter image description here

    Creates a thread pool that reuses a fixed number of threads operatingoff a shared unbounded queue. At any point, at most nThreads threadswill be active processing tasks. If additional tasks are submittedwhen all threads are active, they will wait in the queue until athread is available


    稍微修改了测试,以添加有关工作线程的信息并执行一些额外的任务。
    volatile boolean wifeAlarm = false;
    //...
    service = Executors.newFixedThreadPool(2);
    设置后,执行多个任务:
    service.execute(() -> System.out.println("Woke up fast -" 
    + Thread.currentThread().getName()));
    service.execute(() ->
    {
    try {
    Thread.sleep(5000);
    System.out.println("Woke up lazy - John where are you?? - {"+
    Thread.currentThread().getName()+"}");
    } catch (InterruptedException e){}
    finally { wifeAlarm=true;}
    });
    service.execute(() -> System.out.println("Cleaning - {"
    + Thread.currentThread().getName()+"}"));
    service.execute(() -> System.out.println("Making breakfast - {"
    +Thread.currentThread().getName()+"}"));
    service.execute(() -> System.out.println("Flirt with neighbour - {"
    +Thread.currentThread().getName()+"}"));
    service.execute(() -> System.out.println("Got her number - {"
    +Thread.currentThread().getName()+"}"));
    service.execute(() -> System.out.println("Send hot af pic - {"
    +Thread.currentThread().getName()+"}"));
    service.execute(() -> System.out.println("Remove all proof on phone - {"
    +Thread.currentThread().getName()+"}"));
    service.execute(() ->
    {
    try {
    while (!wifeAlarm)
    Thread.sleep(13);
    System.out.println("Just working my love - {"+
    Thread.currentThread().getName()+"}");
    } catch (InterruptedException e) {}
    });
    输出
    Woke up fast - {pool-1-thread-1}
    Cleaning - {pool-1-thread-1}
    Making breakfast - {pool-1-thread-1}
    Flirt with neighbour - {pool-1-thread-1}
    Got her number - {pool-1-thread-1}
    Send hot af pic - {pool-1-thread-1}
    Remove all proof on phone - {pool-1-thread-1}
    // ~4-5s
    Woke up lazy - John where are you?? - {pool-1-thread-2}
    Just working my love - {pool-1-thread-1}
    这只是另一个可怕的表示:
       {task1} {task2}  {task3}  (..)  {task9}
    ^ ^ ^ ^ (~5s)
    | [Thread2]--- | -------------|---------(...)----------->{x}
    [Thread1] ----->[Thread1]--(..)-[Thread1]----------------------->{x}

    在履历表中:John利用了这个新上下文,多线程池使 都很棒。
    enter image description here
    John可以在线程2执行1的同时执行7个 Action 。对于John来说,更好的是,他能够在线程2完成分配的任务之前完成所有 Action 。约翰现在很安全,由于队列为空,它将完成任务并进入空闲状态。对约翰有好处。
  • thread-2被分配了任务2 。但这一次 sleep 不会导致工作队列增加,因为另一个线程能够同时执行它们。
  • thread-1执行所有 4个重要的任务: 5、6、7和8 。还为它分配了其他4个低优先级任务,能够在另一个线程“繁忙”( hibernate )时清空工作队列。
  • 关于java - 有关Executors.newSingleThreadExecutor()的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66485053/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com