首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >加入两个不同的ExecutorService

加入两个不同的ExecutorService
EN

Stack Overflow用户
提问于 2020-12-19 06:00:48
回答 1查看 99关注 0票数 2

我想加入两个正在ExecutorService中执行的线程。

代码语言:javascript
运行
复制
public class CURD {

  public static ExecutorService executorService = Executors.newCachedThreadPool();
  
 @Autowired
 Logging logging;

  public void Update(List<? extends HBase> save, List<? extends HBase> delete) {
        Thread t = new Thread(() -> {
            System.out.println("Started Main Thread...");
            try {
                Thread.sleep(1500);

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("End Main Thread...");
        },"Thread-1");

        logging.setPredecessor(t);
        executorService.submit(t);
    }
}

第二类:这个类线程应该等待第一个线程完成。但是它不会等待第一个线程完成。我不知道这是否正确的做法。

请有人让我知道如何连接在ExecutorService中执行的两个线程吗?

代码语言:javascript
运行
复制
import static com.demo.executorService;

public class Logging {
   
   private Thread predecessor;
   public void  setPredecessor(Thread t) {
        this.predecessor = t;
    }

  private void loggingInfo() {
      Thread run = new Thread( () ->{
                try {
                    if (predecessor != null) {
                        System.out.println(Thread.currentThread().getName() + " Started");
                        predecessor.join();
                        System.out.println(Thread.currentThread().getName() + " Finished");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            addTask(run);
   }

   public void addTask(Runnable run) {
        System.out.println("Runnable Thread logAround.....");
        CompletableFuture.runAsync((run), executorService).exceptionally(ex -> {
            System.out.println("exception occurred " + ex);
            return null;
        });
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-19 08:00:12

如果要在一组线程之间进行同步,可以使用Java CyclicBarrier类:

一种同步工具,它允许一组线程都等待对方到达一个共同的障碍点。CyclicBarriers在涉及固定大小线程的程序中非常有用,这些线程必须偶尔等待对方。这个屏障被称为循环,因为它可以在等待线程释放后被重用。

为此,首先使用对应的参与者数创建CyclicBarrier对象,即:

代码语言:javascript
运行
复制
private final CyclicBarrier barrier = new CyclicBarrier(NUMBER_OF_PARIES);

从Java文档中可以正式看出,各方是:

必须调用{@链接#等待}的线程数,然后才会触发屏障。

非正式地说,缔约方是必须调用循环屏障并等待的线程数,然后所有线程才能向前迈进。

然后,您需要将屏障实例对象引用传递给每个应该等待的线程,并相应地调用wait (即barrier.await())。如下所示:

代码语言:javascript
运行
复制
  public void Update(..., CyclicBarrier barrier) {
        Thread t = new Thread(() -> {
            System.out.println("Started Main Thread...");
            try {
                 Thread.sleep(1500);
                 barrier.await(); // <--- wait on the barrier
            } catch (InterruptedException | BrokenBarrierException e) {
                 e.printStackTrace();
             }
            System.out.println("End Main Thread...");
        },"Thread-1");
        ...
    }

将此进程重复到必须等待的其他线程。确保各方(即NUMBER_OF_PARIES)的数量与应该在循环屏障上等待的线程数目相匹配,否则将出现死锁。

现在您正在使用cyclic barrier,您可以清理代码的某些部分,例如,您可以删除与Logging类的字段predecessor相关的所有逻辑。

如果您只想让Thread 2等待Thread 1,那么可以使用CountDownLatch

一种同步辅助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。CountDownLatch是用给定的计数初始化的。等待方法阻塞,直到当前计数由于调用countDown()方法而达到零为止,之后所有等待线程都会被释放,并且等待方法的任何后续调用都会立即返回。这是一个一次性现象--计数不能重置。如果需要重置计数的版本,请考虑使用CyclicBarrier。

首先,只使用CountDownLatch计数创建1对象:

代码语言:javascript
运行
复制
private final CountDownLatch block_thread2 = new CountDownLatch(1);

并将其传递给Thread 2,因为您希望这个线程等待Thread 1,所以调用block_thread2.await();

代码语言:javascript
运行
复制
      Thread run = new Thread( () ->{
                   try {
                        ....
                        block_thread2.await(); // wait for Thread 2
                   } catch (InterruptedException e) {
                        // deal with it
                   }
     });
            ...

Thread 1添加wait.countDown();

代码语言:javascript
运行
复制
  public void Update(...) {
        Thread t = new Thread(() -> {
                   System.out.println("Started Main Thread...");
                   try {
                        Thread.sleep(1500);
                        wait.countDown();
                   } catch (InterruptedException e) {
                        // deal with it
            }
            System.out.println("End Main Thread...");
        },"Thread-1");
        ...
    }

因此,以这种方式,Thread 2将等待Thread 1,但Thread 1将永远不会等待Thread 2

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65367131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档