Run two threads that wait one for the other while the main thread continues

How can I start two threads where thread1 is executed first, thread2 is started when thread1 ends, when the main method thread can continue its work without blocking on the other two?

I tried join (), however it needs to be called from a thread that should wait for another, there is no way to do something like thread2.join (thread1); If I call for union inside main (), I therefore effectively stop the execution of the main thread, not just thread2.

So I tried with ExecutorService, but again the problem.

import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class Test { public static void main(String args[]) throws InterruptedException { System.out.println(Thread.currentThread().getName() + " is Started"); class TestThread extends Thread { String name; public TestThread(String name) { this.name = name; } @Override public void run() { try { System.out.println(this + " is Started"); Thread.sleep(2000); System.out.println(this + " is Completed"); } catch (InterruptedException ex) { ex.printStackTrace(); } } @Override public String toString() { return "Thread " + name; } } ExecutorService executor = Executors.newCachedThreadPool(); executor.execute(new TestThread("1")); boolean finished = executor.awaitTermination(1, TimeUnit.HOURS); if(finished) { //I should execute thread 2 only after thread 1 has finished executor.execute(new TestThread("2")); } //I should arrive here while process 1 and 2 go on with their execution System.out.println("Hello"); } } 

#EDIT: why do I need this:

I need this because Thread1 copies elements from the database table to another database, thread2 must copy the link table that refers to the table copied from thread1. Consequently, thread2 should start filling in its bind table only when thread1 has finished, otherwise the whole error is set by the database. Now imagine that I have several threads with different priorities due to complex binding tables, and you have an idea.

+6
source share
7 answers

The second thread can be just as normal (takes the previous thread as an argument):

 public static void main(String[] a) { Thread first = new Thread(new Runnable() { @Override public void run() { } }); Thread second = new MyThread(first); first.start(); second.start(); //continue executing } public static class MyThread extends Thread { private Thread predecessor; public MyThread(Thread predecessor) { this.predecessor = predecessor; } public void run() { if (predecessor != null && predecessor.isAlive()) { try { predecessor.join(); } catch (InterruptedException e) {} } //do your stuff } } 
+3
source

I am sure something is wrong with you, because it should work, and it works:

 new Thread() { @Override public void run() { TestThread t1= new TestThread("1"); TestThread t2= new TestThread("2"); try { t1.start(); t1.join(); t2.start(); t2.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); 

Output:

 main is Started Hello Thread 1 is Started Thread 1 is Completed Thread 2 is Started Thread 2 is Completed 

Another option is to extend TestThread to "Thread 1" to do the work of "Thread 2" after it has been done with its own work. Something like this:

 final TestThread t2= new TestThread("2"); TestThread t1= new TestThread("1") { @Override public void run() { super.run(); //finish t1 work t2.start(); // start t2 work } }; t1.start(); 
+3
source

You can use CountDownLatch :

create it in the main thread, pass it to both streams and call the countdown on it in stream one when it exits, and wait until it is counted at the beginning of stream 2.

+2
source

Why not just start thread1 to start thread2?

 // in main new Thread(new Runnable() { @Override public void run() { // do thread1 work new Thread(new Runnable() { @Override public void run() { /* do thread2 work */ } }).start(); } }).start(); 

However, it is completely unclear why you would like to do this, and not just so that thread1 does 100% of the background work.

+1
source

You can use SingleThreadExecutor to run one task after another Java doc

Thus, it will set your task one by one, and they will be executed sequentially without blocking the main thread

+1
source

Stupid question, but if thread 2 should be executed while thread 1 is running ... why not just start it from thread 1?

Or maybe only thread 1 fires the event, and the main thread can just fire a new one in response to this.

I found this example should work for you.

0
source

You can start two threads one by one using several methods:

  • using the join () method. eg:

     Thread t1=new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 4; i++) { System.out.println("A " + i); } } }); Thread t2=new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 4; i++) { System.out.println("B " + i); } } }); 
    1. using the wait () and notify (): ex methods.

`

 { public class NotiffyAllExample { int flag = 1; public static void main(String[] args) { NotiffyAllExample notiffyAllExample = new NotiffyAllExample(); A1 a = new A1(notiffyAllExample); B1 b = new B1(notiffyAllExample); C1 c = new C1(notiffyAllExample); a.start(); b.start(); } } class A1 extends Thread { NotiffyAllExample notiffyAllExample; public A1(net.citigroup.mexico.pg.test.test.NotiffyAllExample notiffyAllExample) { this.notiffyAllExample = notiffyAllExample; } @Override public void run() { try { synchronized (notiffyAllExample) { for (int i = 0; i < 4; i++) { while (notiffyAllExample.flag != 1) { notiffyAllExample.wait(); } System.out.print("A "); } notiffyAllExample.flag = 2; notiffyAllExample.notifyAll(); } } catch (Exception e) { System.out.println("Exception 1 :" + e.getMessage()); } } } class B1 extends Thread { NotiffyAllExample notiffyAllExample; public B1(NotiffyAllExample notiffyAllExample) { this.notiffyAllExample = notiffyAllExample; } @Override public void run() { try { synchronized (notiffyAllExample) { for (int i = 0; i < 4; i++) { while (notiffyAllExample.flag != 2) { notiffyAllExample.wait(); } System.out.print("B "); } notiffyAllExample.flag = 1; notiffyAllExample.notifyAll(); } } catch (Exception e) { System.out.println("Exception 2 :" + e.getMessage()); } } } } 

`

0
source

Source: https://habr.com/ru/post/948718/


All Articles