Thread2 等待 Thread1 完成才能启动 问题? Java
Thread2 waits Thread1 to complete to start Problem? Java
所以我有一个简单的代码,我想用线程 1 打印值 I 10 次,然后是线程 2 的 10 次,最后打印计数(应该是 20)。我正在使用“.join()”,但结果是执行 Thread1 和 Thread2 的随机时间,然后总和是正确的。怎么可能首先打印所有 Thread's1 循环然后打印 Tread's2 ??
class MyClass extends Thread {
public static synchronized void incount() {
SimpleThreads.count++;
}
public void run() {
for(int i=0; i<10; i++) {
incount();
System.out.println(Thread.currentThread().getId()+" value : " + i);
}
}
}
public class SimpleThreads {
static int count=0;
public static void main(String[] args) {
MyClass thread1 =new MyClass();
MyClass thread2 =new MyClass();
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" Sum : "+count);
}
}
结果:
11 value : 0
10 value : 1
11 value : 1
10 value : 2
11 value : 2
10 value : 3
11 value : 3
11 value : 4
11 value : 5
11 value : 6
11 value : 7
11 value : 8
11 value : 9
10 value : 4
10 value : 5
10 value : 6
10 value : 7
10 value : 8
10 value : 9
Sum : 20
在 thread1
调用 join()
之前,您正在启动 Thread2
。
这就是为什么你的两个线程基本上是同时 运行 并且你的连接不影响任何其他 2 个线程的 run()
。
尝试将您的开始和加入调用代码改成这样;
try{
thread1.start();
thread1.join();
thread2.start();
}
在这种情况下,您不需要在线程 2 上调用 join()
。
如果您希望 thread2
在 thread1
终止后启动,那么您当然可以简单地等待 thread1
终止然后启动 thread2
。但是,使用线程有什么意义呢?
如果你想同时启动 thread1
和 thread2
并且仍然要 thread2
等到 thread1
终止,你可以使用 Java 很多 concurrency utilities, such as Semaphore
下面的代码演示了Semaphore
的用法。如您所见,就像您问题中的代码一样,两个线程 - thread1
和 thread2
- 同时启动。在classMyClass
的run()
方法中,代码尝试获取信号量。方法 acquire()
将阻塞,即它不会 return,直到它成功获取信号量。因此,设法获取信号量的第一个线程将运行,而另一个线程将等待直到第一个线程释放信号量。请注意,我只使用一个许可创建信号量,这意味着在任何时候只有一个线程可以获取信号量。如果在 Semaphore
构造函数的调用中将 1
更改为 2
,您将获得与问题中原始代码完全相同的行为,即两个线程都将 运行同时因为两者都可以立即获取信号量。
另请注意,由于我使用的是信号量,因此我根本不需要调用 Thread.join()
来让一个线程等待另一个线程完成,但由于您想打印 "sum"在"main"线程中,"main"线程需要等待,但它只需要等待第二个线程终止即可。
代码如下:
import java.util.concurrent.Semaphore;
class MyClass extends Thread {
private Semaphore semaphore;
public MyClass(Semaphore semaphore) {
this.semaphore = semaphore;
}
public static synchronized void incount() {
SimpleThreads.count++;
}
public void run() {
try {
semaphore.acquire();
for (int i = 0; i < 10; i++) {
incount();
System.out.println(Thread.currentThread().getId() + " value : " + i);
}
}
catch (InterruptedException xInterrupted) {
xInterrupted.printStackTrace();
}
finally {
semaphore.release();
}
}
}
public class SimpleThreads {
static int count = 0;
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(1);
MyClass thread1 = new MyClass(semaphore);
MyClass thread2 = new MyClass(semaphore);
thread1.start();
thread2.start();
try {
thread2.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" Sum : " + count);
}
}
这里是 运行 上面的代码得到的输出:
13 value : 0
13 value : 1
13 value : 2
13 value : 3
13 value : 4
13 value : 5
13 value : 6
13 value : 7
13 value : 8
13 value : 9
14 value : 0
14 value : 1
14 value : 2
14 value : 3
14 value : 4
14 value : 5
14 value : 6
14 value : 7
14 value : 8
14 value : 9
Sum : 20
所以我有一个简单的代码,我想用线程 1 打印值 I 10 次,然后是线程 2 的 10 次,最后打印计数(应该是 20)。我正在使用“.join()”,但结果是执行 Thread1 和 Thread2 的随机时间,然后总和是正确的。怎么可能首先打印所有 Thread's1 循环然后打印 Tread's2 ??
class MyClass extends Thread {
public static synchronized void incount() {
SimpleThreads.count++;
}
public void run() {
for(int i=0; i<10; i++) {
incount();
System.out.println(Thread.currentThread().getId()+" value : " + i);
}
}
}
public class SimpleThreads {
static int count=0;
public static void main(String[] args) {
MyClass thread1 =new MyClass();
MyClass thread2 =new MyClass();
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" Sum : "+count);
}
}
结果:
11 value : 0
10 value : 1
11 value : 1
10 value : 2
11 value : 2
10 value : 3
11 value : 3
11 value : 4
11 value : 5
11 value : 6
11 value : 7
11 value : 8
11 value : 9
10 value : 4
10 value : 5
10 value : 6
10 value : 7
10 value : 8
10 value : 9
Sum : 20
在 thread1
调用 join()
之前,您正在启动 Thread2
。
这就是为什么你的两个线程基本上是同时 运行 并且你的连接不影响任何其他 2 个线程的 run()
。
尝试将您的开始和加入调用代码改成这样;
try{
thread1.start();
thread1.join();
thread2.start();
}
在这种情况下,您不需要在线程 2 上调用 join()
。
如果您希望 thread2
在 thread1
终止后启动,那么您当然可以简单地等待 thread1
终止然后启动 thread2
。但是,使用线程有什么意义呢?
如果你想同时启动 thread1
和 thread2
并且仍然要 thread2
等到 thread1
终止,你可以使用 Java 很多 concurrency utilities, such as Semaphore
下面的代码演示了Semaphore
的用法。如您所见,就像您问题中的代码一样,两个线程 - thread1
和 thread2
- 同时启动。在classMyClass
的run()
方法中,代码尝试获取信号量。方法 acquire()
将阻塞,即它不会 return,直到它成功获取信号量。因此,设法获取信号量的第一个线程将运行,而另一个线程将等待直到第一个线程释放信号量。请注意,我只使用一个许可创建信号量,这意味着在任何时候只有一个线程可以获取信号量。如果在 Semaphore
构造函数的调用中将 1
更改为 2
,您将获得与问题中原始代码完全相同的行为,即两个线程都将 运行同时因为两者都可以立即获取信号量。
另请注意,由于我使用的是信号量,因此我根本不需要调用 Thread.join()
来让一个线程等待另一个线程完成,但由于您想打印 "sum"在"main"线程中,"main"线程需要等待,但它只需要等待第二个线程终止即可。
代码如下:
import java.util.concurrent.Semaphore;
class MyClass extends Thread {
private Semaphore semaphore;
public MyClass(Semaphore semaphore) {
this.semaphore = semaphore;
}
public static synchronized void incount() {
SimpleThreads.count++;
}
public void run() {
try {
semaphore.acquire();
for (int i = 0; i < 10; i++) {
incount();
System.out.println(Thread.currentThread().getId() + " value : " + i);
}
}
catch (InterruptedException xInterrupted) {
xInterrupted.printStackTrace();
}
finally {
semaphore.release();
}
}
}
public class SimpleThreads {
static int count = 0;
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(1);
MyClass thread1 = new MyClass(semaphore);
MyClass thread2 = new MyClass(semaphore);
thread1.start();
thread2.start();
try {
thread2.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(" Sum : " + count);
}
}
这里是 运行 上面的代码得到的输出:
13 value : 0
13 value : 1
13 value : 2
13 value : 3
13 value : 4
13 value : 5
13 value : 6
13 value : 7
13 value : 8
13 value : 9
14 value : 0
14 value : 1
14 value : 2
14 value : 3
14 value : 4
14 value : 5
14 value : 6
14 value : 7
14 value : 8
14 value : 9
Sum : 20