如何启动thread1首先执行的两个线程,thread2在thread1结束时启动,而main方法线程可以继续工作而不锁定另外两个?
我尝试过join()但是需要从必须等待另一个的线程调用它,没有办法像thread2.join(thread1)那样做; 如果我在main()中调用连接,那么我实际上会停止执行主线程而不仅仅是thread2。
因此我尝试使用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:为什么我需要这个:
我需要这个,因为Thread1将数据库表中的元素复制到另一个数据库中,thread2必须复制一个引用从thread1复制的表的链接表。 因此,thread2只有在thread1完成时才开始填充其链接表,否则数据库会给出完整性错误。 现在想象一下,由于复杂的链接表,我有几个不同优先级的线程,你有一个想法。
答案 0 :(得分:3)
我很确定你遇到了错误,因为这必须有效并且确实有效:
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();
输出是:
main is Started
Hello
Thread 1 is Started
Thread 1 is Completed
Thread 2 is Started
Thread 2 is Completed
另一种选择是扩展“线程1”的TestThread,以便在完成自己的工作后执行“线程2”的工作。类似的东西:
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();
答案 1 :(得分:3)
第二个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
}
}
答案 2 :(得分:2)
您可以使用CountDownLatch:
在主线程中创建它,将它传递给两个线程,并在它退出时在线程1中调用倒计时,并等待它在线程2的开头倒计时。
答案 3 :(得分:1)
为什么不让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();
然而,为什么你不想做这个,而不是让thread1做100%的后台工作,这一点都不清楚。
答案 4 :(得分:1)
您可以使用SingleThreadExecutor在另一个Java doc
之后运行一个任务因此它将一个接一个地执行您的任务,它们将按顺序执行而不会阻塞主线程
答案 5 :(得分:1)
尝试一下,这将按预期工作。 两个线程打印出奇数甚至一个接一个,并且主线程尽快退出。
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");
}
}
答案 6 :(得分:0)
答案 7 :(得分:0)
您可以使用以下几种方法逐个运行两个线程:
使用join()方法。例如:
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());
}
}
}
}
`