【问题标题】:synchronizing thread in javajava中的同步线程
【发布时间】:2012-06-28 15:42:53
【问题描述】:

我正在为多线程实现 java Runnable 接口。我有一些n 线程数。每个线程都有自己的生命。我想等到所有线程的生命都到期。可以说以下是这种情况

for(int i = 0; i< k;i++){
 Thread thread1 = new Thread(new xyz())
 Thread thread2 = new Thread(new abc())
 Thread thread3 = new Thread(new mno())
 thread1.start();
 thread2.start();
 thread3.start();
}

我正在做以下同步它。我不知道这是否正确。请让我知道我该怎么做?有什么方法可以检查我的线程程序是否正常工作?

          if(thread2.isAlive())
                try {
                    thread2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            if(thread1.isAlive())
                    try {
                        thread1.join();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
            if(thread3.isAlive())
                try {
                        thread3.join();
                } catch (InterruptedException e) {
                e.printStackTrace();
                    }   

【问题讨论】:

    标签: java multithreading synchronization


    【解决方案1】:

    您可以将您的 Runnables 添加到 ExecutorService 并调用 shutdown / awaitTermination,这将在所有任务完成后返回。 javadoc 中有一些示例 - 总而言之,您可以编写如下内容:

    ExecutorService executor = Executors.newFixedThreadPool(3);
    
    executor.submit(runnable1);
    executor.submit(runnable2);
    executor.submit(runnable3);
    
    executor.shutdown();
    boolean allRunnableAreDone = executor.awaitTermination(60, TimeUnit.SECONDS);
    
    // This line is reached once all runnables have finished their job
    // or the 60 second timeout has expired
    

    【讨论】:

    • 检查awaitTermination 的返回值并在其上循环是个好主意,以防它需要比您指定的时间更长的时间才能完成。
    • 或者打电话给awaitTermination(Long.MAX_VALUE, ...),而不是仅仅60秒。
    【解决方案2】:

    虽然来自@assylias 的ExecutorService 回答很好,这里有更多关于join() 的信息。

    您无需在join() 之前测试isAlive()。 Thread.join() 代码已经这样做了。这是来自那里的代码的sn-p:

    while (isAlive()) {
        wait(0);
    }
    

    所以你需要做的就是加入你的线程:

       try {
           thread2.join();
           thread1.join();
           thread3.join();
       } catch (InterruptedException e) {
           // always a good pattern
           Thread.currentThread().interrupt();
           e.printStackTrace();
       }
    

    【讨论】:

    • 我不知道这个。这似乎是最简单的。
    【解决方案3】:

    作为一个简单的解决方案,您可以将所有线程放在一个列表中,然后在它们启动后对它们调用 join:

    List<Thread> threads = new ArrayList<>();
    for(int i = 0; i< k;i++)
    {
      //create threads
      Thread thread1 = new Thread(new xyz());
      Thread thread2 = new Thread(new abc());
      Thread thread3 = new Thread(new mno());
    
      //store threads
      threads.add(thread1);
      threads.add(thread2);
      threads.add(thread3);
    
      //start threads
      thread1.start();
      thread2.start();
      thread3.start();
    }
    
    //join all threads
    for(Thread t : threads)
       t.join();
    
    //You are here after all threads have terminated
    

    【讨论】:

      【解决方案4】:

      Java 包含在java.util.concurrent 中执行此类操作的机制。

      在您的情况下,您可能需要CountDownLatch 或ExecutorService

      【讨论】:

        【解决方案5】:

        join() 方法不加入线程,而是加入锁定对象。等待线程必须调用lockObject.join(),工作线程在完成后必须调用lockObject.notify()。等待的线程将被通知并可以继续其工作。您还需要在这些调用周围使用synchronize 块。

        我也推荐像 assylias 提到的 Executor,它比自己实现这个行为要容易得多。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-16
          • 1970-01-01
          • 1970-01-01
          • 2012-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多