[英]Execute two threads which wait one for the other while main thread continues
How can I start two threads where thread1 executes first, thread2 starts when thread1 ends while the main method thread can continue its work without locking on the other two? 如何启动thread1首先执行的两个线程,thread2在thread1结束时启动,而main方法线程可以继续工作而不锁定另外两个?
I have tried join() however it needs to be called from the thread which has to wait for the other, there's no way to do something like thread2.join(thread1); 我已经尝试了join()但是它需要从线程调用,它必须等待另一个,没有办法像thread2.join(thread1)那样做; If I call for a join inside main() I therefore effectively stop execution of the main thread and not only of thread2.
如果我在main()中调用连接,那么我有效地停止执行主线程,而不仅仅是thread2。
I therefore tried with ExecutorService but again same problem. 因此,我尝试使用ExecutorService,但同样的问题。
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 I need this: #EDIT:为什么我需要这个:
I need this because Thread1 copies elements from a database table into another database, thread2 has to copy a linking table which references the table copied from thread1. 我需要这个,因为Thread1将数据库表中的元素复制到另一个数据库中,thread2必须复制一个引用从thread1复制的表的链接表。 Consequently thread2 has to start populating its linking table only when thread1 has finished otherwise an integrity error is given by the database.
因此,thread2只有在thread1完成时才开始填充其链接表,否则数据库会给出完整性错误。 Now imagine I have several threads with different priorities due to complex linking tables and you have an idea.
现在想象一下,由于复杂的链接表,我有几个不同优先级的线程,你有一个想法。
The second Thread can be custom like this (takes as argument the previous thread): 第二个Thread可以像这样自定义(作为前一个线程的参数):
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
}
}
I am pretty sure you got something wrong because this must work and it does work: 我很确定你有错误,因为这必须有效,它确实有效:
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();
The ouput is: 输出是:
main is Started
Hello
Thread 1 is Started
Thread 1 is Completed
Thread 2 is Started
Thread 2 is Completed
Another option would be to extend the TestThread for the "Thread 1" to execute the work of "Thread 2" after it has been done with its own work. 另一个选择是扩展“线程1”的TestThread,以便在完成自己的工作后执行“线程2”的工作。 Something similar to 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();
You can use a CountDownLatch : 您可以使用CountDownLatch :
create it in the main thread, pass it on to both threads and call countdown on it in thread one when it exits and await it being counted down at the start of thread 2. 在主线程中创建它,将它传递给两个线程,并在它退出时在线程1中调用倒计时,并等待它在线程2的开始倒计时。
Why not just have thread1 be the one to start thread2? 为什么不让thread1成为启动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's not at all clear why you would want to do this as opposed to just having thread1 do 100% of the background work. 但是,完全不清楚为什么要这样做而不是让thread1完成100%的后台工作。
Try this, This will work as expected. 试试这个,这将按预期工作。 Two threads printing odd and even one after another and main exiting as soon as possible.
两个线程一个接一个地打印奇数和偶数,并且主要尽快退出。
public class YoThreD {
static boolean isThread1 = false;
public static synchronized boolean isThread1() {
return isThread1 = !isThread1;
}
public static void main(String args[]) {
Runnable runnableObject = new Runnable() {
@Override
public void run() {
synchronized (this) {
for (int i = 1; i <= 100; i++) {
try {
if (Thread.currentThread().getName().equals("thread1")) {
if (isThread1()){
System.out.println(Thread.currentThread().getName() + " : " + i);
}else{
this.notify();
this.wait();
}
} else {
if (!isThread1()){
System.out.println(Thread.currentThread().getName() + " : " + i);
this.notify();
this.wait();
}
else{
}
}
} catch (Exception e) {
}
}
}
}
};
Thread thread1 = new Thread(runnableObject);
thread1.setName("thread1");
thread1.start();
Thread thread2 = new Thread(runnableObject);
thread2.setName("thread2");
thread2.start();
System.out.println(Thread.currentThread().getName() + "Main thread finished");
}
}
Silly question, but if thread 2 is supposed to execute when thread 1 is done... why not just start it from thread 1? 愚蠢的问题,但是如果线程2在线程1完成时应该执行...为什么不从线程1开始呢?
Or maybe just have thread 1 trigger an event and the main thread can just launch the new one in response to that. 或者也许只是让线程1触发一个事件,主线程就可以启动新线程来响应。
You can run two thread one after other by using several ways: 您可以使用以下几种方法逐个运行两个线程:
by using join() method. 通过使用join()方法。 ex:
例如:
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); } } });
` `
{
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());
}
}
}
}
` `
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.