可能重复:
Trying to loop 3 threads in a specific order everytime
我想从两个线程一个接一个地访问同一个对象的两个不同方法。这是我的代码,
public class ThreadCoordination
{
private Thread threadSayHello;
private Thread threadSayWorld;
private boolean threadSayWorldStarted = false;
public ThreadCoordination()
{
createThreads();
}
private void createThreads()
{
threadSayWorld = new Thread(new Runnable()
{
public void run()
{
try
{
// while (true)
{
sayWorld();
}
}
catch (InterruptedException ex)
{}
}
});
threadSayHello = new Thread(new Runnable()
{
public void run()
{
try
{
// while (true)
{
sayHello();
if (!threadSayWorldStarted)
{
threadSayWorldStarted = true;
threadSayWorld.start();
}
}
}
catch (InterruptedException ex)
{}
}
});
threadSayHello.start();
}
private synchronized void sayHello() throws InterruptedException
{
System.out.print("Hello ");
}
private synchronized void sayWorld() throws InterruptedException
{
System.out.println("World!");
}
public static void main(String[] args)
{
new ThreadCoordination();
}
}
如果我在(true)时取消注释,那么我会期待像这样的输出,
Hello World!
Hello World!
Hello World!
Hello World!
...
请指导我该怎么做。 拉加。
我不知道是否可以编辑已关闭的帖子。据我所知,我只想发布解决方案。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class SequenceAccess
{
private ReentrantLock myLock;
private Condition ensureSequence;
private int sequenceNo = 1;
public SequenceAccess()
{
myLock = new ReentrantLock();
ensureSequence = myLock.newCondition();
startThreads();
}
private void startThreads()
{
new Thread(new Runnable()
{
public void run()
{
try
{
while (true)
method1();
}
catch (InterruptedException ex)
{}
}
}).start();
new Thread(new Runnable()
{
public void run()
{
try
{
while (true)
method2();
}
catch (InterruptedException ex)
{}
}
}).start();
new Thread(new Runnable()
{
public void run()
{
try
{
while (true)
method3();
}
catch (InterruptedException ex)
{}
}
}).start();
}
private void method1() throws InterruptedException
{
myLock.lock();
try
{
while (sequenceNo != 1)
ensureSequence.await();
sequenceNo = 2;
System.out.println("Method 1");
ensureSequence.signalAll();
}
finally
{
myLock.unlock();
}
}
private void method2() throws InterruptedException
{
myLock.lock();
try
{
while (sequenceNo != 2)
ensureSequence.await();
sequenceNo = 3;
System.out.println("Method 2");
ensureSequence.signalAll();
}
finally
{
myLock.unlock();
}
}
private void method3() throws InterruptedException
{
myLock.lock();
try
{
while (sequenceNo != 3)
ensureSequence.await();
sequenceNo = 1;
System.out.println("Method 3");
ensureSequence.signalAll();
}
finally
{
myLock.unlock();
}
}
public static void main(String[] args)
{
new SequenceAccess();
}
}
答案 0 :(得分:1)
JVM 不保证线程执行的顺序
事实上,JVM规范可以完全通过运行hello线程直到它终止然后运行world线程直到它终止(程序已写入)来满足
您需要在两个线程之间引入某种令牌,然后让该令牌来回穿梭。
令牌可以像布尔一样简单,如果输出了hello则为true,如果输出了world则为false。
然后每个线程必须旋转(或等待条件 - 条件更好的性能),直到布尔匹配其预期状态。
我建议您掌握最优秀的“实践中的Java并发”一书
答案 1 :(得分:0)
这个任务确实有点奇怪,因为这本质上是一个单线程的任务。虽然,我知道应用程序可能变得非常复杂并且需要许多奇怪的东西,也有多个线程。
您可以创建任意类型的两个私有对象,例如Object
,用作“事件”。每个线程的循环应该wait()
用于其中一个事件对象,然后执行其任务(打印字符串),然后notify()
另一个事件对象,然后再次重复循环和wait()
。另一个线程应该做同样的事情,但交换事件对象。
启动两个线程,然后notify()
第一个事件对象。行动开始了!