我想运行两个线程,这两个线程共享一个方法,以打印出一些东西。我希望将以下内容作为输出:
a b a b a b 第一个线程打印'a‘,第二个线程打印'b’。我设法打印了一次,但我不能包括一个适当的循环来交换指纹。
我写了这段代码来执行下面的代码:
public void run() {
while(i<10) {
synchronized(this) {
while (turn!=turn) {
try {
turn=!turn;
wait();
sleep(10);
}
catch(InterruptedException ie){}
}
printThreadOutput();
turn=!turn;
i++;
notifyAll();
}
}
}有什么建议吗?
发布于 2013-03-31 09:20:16
一个简单的解决方案是使用java.util.concurrent.locks.Lock,它将执行所需的所有等待和通知操作:
public class ThreadTest {
private static final Lock lock = new ReentrantLock();
public static final void main(String[] args) {
Runnable aRun;
Runnable bRun;
aRun = new Runnable() {
public void run() {
while (true) {
lock.lock();
System.out.println("a");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
lock.unlock();
}
}
};
bRun = new Runnable() {
public void run() {
while (true) {
lock.lock();
System.out.println("b");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
lock.unlock();
}
}
};
Thread aThread = new Thread(aRun);
Thread bThread = new Thread(bRun);
aThread.start();
bThread.start();
}
}不使用监视器你也可以这样做,但正如@noahz谦虚地指出的那样,它使用的Spinlock效率不高。
public class ThreadTest {
private static volatile Boolean isATurn = true;
public static void main(String[] args) {
Runnable aRun;
Runnable bRun;
aRun = new Runnable() {
public void run() {
while (true) {
while (!isATurn) {
}
System.out.println("a");
isATurn = false;
}
}
};
bRun = new Runnable() {
public void run() {
while (true) {
while (isATurn) {
}
System.out.println("b");
isATurn = true;
}
}
};
Thread aThread = new Thread(aRun);
Thread bThread = new Thread(bRun);
aThread.start();
bThread.start();
}
}据我所知,这保证了不会出现死锁,但如果其中一个线程没有终止,则可能会出现饥饿,因为另一个线程将在等待它。然而,对于这样一个简单的例子来说,这不应该是一个问题。监视器也比使用轮询更可取,但是稍微复杂一些。
发布于 2013-03-31 09:29:52
现在是凌晨三点半,我想睡觉了。这是我想出来的:
class TurnHolder {
private volatile int currentTurn;
public void setNextTurn() {
this.currentTurn = currentTurn^1;
}
public int getCurrentTurn() {
return currentTurn;
}
}
class Printer implements Runnable {
private String toPrint;
private TurnHolder sharedResource;
private int turn;
Printer(String toPrint, TurnHolder sharedResource, int turn) {
this.toPrint = toPrint;
this.sharedResource = sharedResource;
this.turn = turn;
}
@Override
public void run() {
while (true) {
synchronized (sharedResource) {
if (sharedResource.getCurrentTurn() != turn)
try {
sharedResource.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(toPrint);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
sharedResource.setNextTurn();
sharedResource.notifyAll();
}
}
}运行它的一种方法是:
TurnHolder sharedResource = new TurnHolder();
Printer printerA = new Printer("a", sharedResource, 0);
Printer printerB = new Printer("b", sharedResource, 1);
new Thread(printerA).start();
new Thread(printerB).start();这样,你的sharedResource将保持转弯的记忆,同步它允许你在该转弯时做你必须做的事情,然后你可以切换转弯。Thread.sleep只是为了让你能以很快的速度看到打印结果。System.out.println(toPrint);就是您的printThreadOutput();
附言:欢迎就如何改进代码提出建议。
发布于 2013-03-31 09:20:12
while循环没有执行,因为它的条件始终为false。完全删除内部的while,你不需要它。turn变量是不需要的。在捕获InterruptedException.时,synchronize和Thread.sleep(5)将使线程轮流使用。
printlnhttps://stackoverflow.com/questions/15725207
复制相似问题