我正在编写具有2个线程的简单多线程代码。一个打印0到500之间的偶数,另一个打印1到500之间的奇数。我希望通过改变线程彼此交互的方式按顺序打印数字。它工作得很好,但由于某种原因,线程最终会挂起......即使我从run()返回...
另外,我正确使用旗帜还是有更好的方法?
public class Multithreading {
public static Even even;
public static Odd odd;
public static void main(String[] args) throws InterruptedException{
even = new Even();
odd = new Odd();
Thread a = new Thread(even);
Thread b = new Thread(odd);
a.start();
b.start();
}
public static class Odd implements Runnable {
public boolean running;
public void run() {
odd.pauseThread();
while (!running) {}
for (int i = 1; i <= 500; i += 2) {
System.out.println(i);
odd.pauseThread();
while (!running) {
even.resumeThread();
if (i > 500) {
return;
}
}
}
}
public void pauseThread() {
running = false;
}
public void resumeThread() {
running = true;
}
}
public static class Even implements Runnable {
public boolean running;
public void run() {
System.out.println("Hello World");
for (int i = 0; i <= 500; i += 2) {
System.out.println(i);
even.pauseThread();
while (!running) {
odd.resumeThread();
if (i > 500) {
return;
}
}
}
}
public void pauseThread() {
running = false;
}
public void resumeThread() {
running = true;
}
}
}
答案 0 :(得分:0)
您很快就会了解到,多线程编程非常困难,需要非常好地理解线程如何与内存以及彼此之间的交互。
从您的程序中,我可以说您需要投入更多时间来学习并发编程的基础知识。
我可以看到的主要问题:
even
和odd
个实例的静态全局和非同步使用。running
变量的非同步使用。if (i > 500) {
最后一点肯定会导致至少有一个线程永远不会退出,从而产生“挂起”。但我确信其他观点也会导致竞争条件,并可能是影响因素。
我运行了你的程序,我发现除了“挂起”之外,我从来没有真正得到正确的打印结果,并且经常会得到不一致的结果。
这是一个工作程序,试图遵循您的一般设计,同时解决上述问题。阅读这是如何工作的将是你的功课。
public class Multithreading {
public static void main(String[] args) {
SharedData sharedData = new SharedData();
Even even = new Even(sharedData);
Odd odd = new Odd(sharedData);
Thread a = new Thread(even);
Thread b = new Thread(odd);
a.start();
b.start();
}
private static class SharedData {
public final Object syncObject = new Object();
public boolean evensTurn = true;
}
private static class Odd implements Runnable {
private final SharedData sharedData;
public Odd(SharedData sharedData) {
this.sharedData = sharedData;
}
@Override
public void run() {
for (int i = 1; i <= 500; i += 2) {
synchronized (this.sharedData.syncObject) {
while (this.sharedData.evensTurn) {
try {
this.sharedData.syncObject.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(i);
this.sharedData.evensTurn = true;
this.sharedData.syncObject.notify();
}
}
}
}
private static class Even implements Runnable {
private final SharedData sharedData;
public Even(SharedData sharedData) {
this.sharedData = sharedData;
}
@Override
public void run() {
for (int i = 0; i <= 500; i += 2) {
synchronized (this.sharedData.syncObject) {
while (!this.sharedData.evensTurn) {
try {
this.sharedData.syncObject.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(i);
this.sharedData.evensTurn = false;
this.sharedData.syncObject.notify();
}
}
}
}
}
答案 1 :(得分:0)
您的问题看起来像生产者/消费者问题。 请检查以下链接 http://www.codeproject.com/Tips/813407/Producer-Consumer-Problem
只需用户等待并通知线程通信。