Java 如何让两个线程互相等待结果?
下面是我的示例代码Java 如何让两个线程互相等待结果?,java,multithreading,Java,Multithreading,下面是我的示例代码 class A implements Runnable{ //stuff Thread thr = new Thread(this); boolean flag; public void run() { while(true){ if(condition)flag = true; } } } class B implements Runnable{ //stuff A a = new A(); Thread thr = new Thr
class A implements Runnable{
//stuff
Thread thr = new Thread(this);
boolean flag;
public void run()
{
while(true){
if(condition)flag = true;
}
}
}
class B implements Runnable{
//stuff
A a = new A();
Thread thr = new Thread(this);
public void run()
{
while(true){
//i ll do some thing here
if(a.flag == true)System.out.println("Kaboom");
}
}
public static void main(String[] args)
{
B b = new B();
}
}
所以问题是我在a之前启动b,我希望b等待直到a.flag==true触发“Kaboom”,而a.thr必须等待b在run()方法中执行其工作。我试过了,但没用
class A implements Runnable{
//stuff
Thread thr = new Thread(this);
boolean flag;
public void run()
{
while(true){
if(condition)flag = true;
synchronized(B.class){
this.flag=true;
B.class.notifyAll();
}
}
}
}
class B implements Runnable{
//stuff
A a = new A();
Thread thr = new Thread(this);
public void run()
{
while(true){
synchronized(this){
while(a.flag!=true)
{
this.wait();
}}
}
}
public static void main(String[] args)
{
B b = new B();
}}
我的同步块中一定有问题,但我不知道是什么问题。这可能是一个愚蠢的问题,但我只是JAVA的初学者,我并不真正了解线程的内容以及它是如何工作的。请帮助我您创建了Runnable,但没有在线程中启动它 正确的一个:
import java.lang.*;
import java.util.concurrent.atomic.*;
class A implements Runnable {
AtomicBoolean flag;
AtomicBoolean condition;
A() {
flag = new AtomicBoolean();
condition = new AtomicBoolean();
}
public void run(){
while (true) {
System.out.println("A");
if (condition.get()) {
flag.set(true);
return ;
}
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}
class B implements Runnable {
A a;
B() {
a = new A();
}
public void run() {
while (true) {
System.out.println("B");
if (a.flag.get()) {
System.out.println("Kaboom");
return ;
}
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
B b = new B();
new Thread(b).start();
new Thread(b.a).start();
b.a.condition.set(true);
}
}
我喜欢您最初使用wait/notifyAll使线程在满足恢复运行的条件之前不使用CPU的方法。这里有一个保持这种方法的解决方案 请注意: 1-在类对象上同步时要小心。除非您真的想同步整个类,否则请创建一个对象并将其用作锁 2-使用
volatile
关键字确保Java不会创建变量的线程本地版本,并且对变量值的更改会立即反映到其他线程
public class Threads {
private final Object lock = new Object();
private volatile boolean flag;
class RunnableA implements Runnable {
private volatile boolean condition = false;
@Override
public void run() {
while (true) {
if (condition) {
if (!flag) {
synchronized (lock) {
System.out.println("Setting Flag to True");
flag = true;
lock.notifyAll();
}
}
} else {
System.out.println("Condition is False");
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
}
}
}
}
}
class RunnableB implements Runnable {
@Override
public void run() {
while (true) {
while (flag == false) {
synchronized (lock) {
if (flag == false) {
try {
lock.wait();
} catch (InterruptedException ex) {
}
}
}
}
System.out.println("Kaboom");
}
}
}
public void run() {
RunnableA runnableA = new RunnableA();
RunnableB runnableB = new RunnableB();
Thread t1 = new Thread(runnableA);
Thread t2 = new Thread(runnableB);
t1.start();
t2.start();
try {
Thread.sleep(5000L);
} catch (InterruptedException ex) {
}
runnableA.condition = true;
}
public static void main(String[] args) {
new Threads().run();
}
}
您是否考虑过使用Thread.Join()这样,a必须在B启动之前完成。join()方法将终止线程,我不希望这样happen@ChiếnTrần更新。顺便说一句,您可以阅读《Java并发性实践》一书,这本书非常棒。值得注意的是,对于这个问题,AtomicBoolean有点矫枉过正(尽管它不会造成伤害)。读取或写入布尔值本身就是原子的。除非您使用诸如getAndSet或compareAndSet之类的确保原子读写的东西,否则使用常规布尔值就可以了,不过您应该声明它是易失的,以避免JVM在线程之间复制它。@andreban哦,thx。我想得太多了,这可能更简单。谢谢你的帮助,但这在我的情况下似乎不起作用。我可以这样说我的问题吗。你们都知道蛇的游戏,对吗?我的想法是创建2个可运行类,类A是蛇头(按下箭头,它会移动到边缘),类B是框架随机生成框架中的“食物”。只有在先前的食物已经被吃掉的情况下,框架才能生成食物。所以B对象必须等到一个对象吃了食物。你能告诉我怎么做吗,先生?我想这里的关键是在蛇吃了食物后将标志重置为false,但我不知道该将该命令放在哪里。因此,每当头部“吃”食物时,你需要重置标志并调用你在食物创建者线程上使用的锁上的notify。只需使用线程正在使用的同一线程。话虽如此,是否有任何特殊的理由将游戏创建为多线程?创建单线程通常比较简单。非常感谢你的建议,我刚刚创建了单线程游戏。