Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何让两个线程互相等待结果?_Java_Multithreading - Fatal编程技术网

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。只需使用线程正在使用的同一线程。话虽如此,是否有任何特殊的理由将游戏创建为多线程?创建单线程通常比较简单。非常感谢你的建议,我刚刚创建了单线程游戏。