英文:
Thread2 waits Thread1 to complete to start Problem? Java
问题
以下是代码的翻译部分:
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);
}
}
结果:
10 value : 0
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
英文:
So I have a simple code that I want to print the value I 10 times with Thread1, after that 10 times of Thread2 and at the end, print the count ( it should be 20). I am using the ".join()" but the result is executing random times of Thread1 and Thread2 and then the Sum is correct. How can is it possible to print first all the Thread's1 loop and then the 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);
}
}
The Result :
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
</details>
# 答案1
**得分**: 3
你在调用```join()```等待```thread1```之前就启动了```Thread2```。这就是为什么你的两个线程基本上在同时运行,而且你的```join```不会影响另一个两个线程的任何一个的```run()```。
尝试将你的启动和等待调用代码更改为以下内容:
```java
try{
thread1.start();
thread1.join();
thread2.start();
}
在这种情况下,你不需要在thread2
上调用join()
。
英文:
You are starting Thread2
before calling the join()
on thread1
.<br>
That is why your both threads are basically running simultaneously and your join is not affecting the run()
of any other the 2 threads.
Try to change your start and join calling code to something like this;
try{
thread1.start();
thread1.join();
thread2.start();
}
You shouldn't need to call join()
on thread2 in this case.
答案2
得分: 2
以下是您提供的代码的翻译部分:
如果你希望thread2
在thread1
终止后启动,那么当然可以简单地等待thread1
终止,然后启动thread2
。但这样一来,使用线程还有什么意义呢?
如果你想同时启动thread1
和thread2
,并且仍然希望thread2
等待直到thread1
终止,你可以使用Java的许多并发工具之一,比如Semaphore(信号量)。
下面的代码演示了Semaphore
的使用。正如你在问题中的代码中所看到的,thread1
和thread2
这两个线程会在同一时间启动。在MyClass
类的run()
方法中,代码尝试获取信号量。acquire()
方法将会阻塞,也就是说,它只有在成功获取信号量时才会返回。因此,第一个成功获取信号量的线程将会运行,而另一个线程将等待,直到第一个线程释放信号量。注意,我使用了一个许可证来创建信号量,这意味着在任何给定时间只有一个线程可以获取信号量。如果你在调用Semaphore
构造函数时将1
更改为2
,你将会得到与你在问题中的原始代码中相同的行为,也就是两个线程将会同时运行,因为它们都可以立即获取信号量。
另请注意,由于我使用了信号量,我根本不需要调用Thread.join()
来使一个线程等待另一个线程完成,但由于你想要在“主”线程中打印“总和”,所以“主”线程需要等待,但它只需要等待第二个线程终止。
以下是代码:
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
英文:
If you want thread2
to start after thread1
terminates, then of-course you can simply wait for thread1
to terminate and then launch thread2
. But then, what is the point of using threads?
If you want to launch thread1
and thread2
at the same time and still have thread2
wait until thread1
terminates, you can use one of Java's many concurrency utilities, such as Semaphore
The below code demonstrates the use of Semaphore
. As you can see, just as in the code in your question, both threads - thread1
and thread2
- are launched at the same time. In the run()
method of class MyClass
, the code tries to acquire the semaphore. Method acquire()
will block, i.e. it will not return, until it succeeds in acquiring the semaphore. Hence the first thread that manages to acquire the semaphore will run, while the other thread will wait until the first thread releases the semaphore. Note that I create the semaphore with only one permit which means that only one thread can acquire the semaphore at any one time. If you change the 1
to a 2
in the call to the Semaphore
constructor, you will get exactly the same behavior as in your original code in your question, i.e. both threads will run simultaneously because both can immediately acquire the semaphore.
Note also that since I am using a semaphore, I don't need to call Thread.join()
at all in order to have one thread wait until the other completes, but since you want to print the "sum" in the "main" thread, the "main" thread needs to wait, but it only needs to wait for the second thread to terminate.
Here is the code:
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);
}
}
And here is the output obtained when running the above code:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论