线程通知等待后不工作问题-java

3j86kqsm  于 2021-06-29  发布在  Java
关注(0)|答案(3)|浏览(373)

我找不到问题,有人能帮我吗。

public class Achterbahn {

private final Object monitor = new Object();

public   synchronized void test() throws InterruptedException {

        //monitor.wait();

        System.out.println("car");
        wait();
        System.out.println("car");

}

public  synchronized void Passagier() throws InterruptedException {
    Thread.sleep(2000);

        System.out.println("p");

        notify();

    //b.t1.notify();

}
public static void main(String []args) throws InterruptedException {

    Thread t4 = new Thread(new Runnable() {

        @Override
        public void run() {
            Achterbahn b = new Achterbahn();
            try {
                b.Passagier();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    });
    Thread t5= new Thread(new Runnable() {

        @Override
        public void run() {
            Achterbahn b = new Achterbahn();
            try {
                b.test();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    });

    new Thread(t4).start();
    new Thread(t5).start();     
      t5.join();
      t4.join();

}

   }

输出为:p车
它似乎是通知工作,我想打印也车在最后,但我不知道为什么它不工作
我希望有人能帮助我。尽快。
我在同一个类中有所有的方法,我也尝试过sepreate类,但是没有用

2admgd59

2admgd591#

你做错了好几件事。
只启动c的一个示例。然后使用该示例调用您的方法。不同的示例在同步方法中不共享监视器
当你开始两个新的线程的时候。只需按如下方式启动它们:

t4.start();
t5.start();

主要问题是 t4 先开始,然后马上睡觉。所以呢 t5 直到睡眠结束才开始。但到那时 notify() 等待 t4wait() 在中调用 t5 因此 wait 我永远也看不到。所以你需要付出 t4 在睡觉前开始的机会。有几种方法可以解决这个问题。一种是使用一个标志来表示另一种方法已经就绪。但不要使用紧密的while循环。放一个 sleep 在里面呆了一小段时间。我在下面举了一个例子。我还为线程分配了名称以匹配变量。

public class C {
    boolean ready = false;

    public synchronized void test() throws InterruptedException {
        System.out.println("Current thread = " + Thread.currentThread().getName());     
        ready = true;
        System.out.println("car");
        wait();
        System.out.println("car");
    }

    public synchronized void Passagier() throws InterruptedException {
        Thread.sleep(4000);
        System.out.println("Current thread = " + Thread.currentThread().getName());
        System.out.println("p");
        notify();

    }

    public static void main(String[] args)
            throws InterruptedException {
        C b = new C();
        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while(!b.ready) {
                        Thread.sleep(100);
                    }
                    b.Passagier();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        },"t4");

        Thread t5 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    b.test();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        },"t5");
        System.out.println("Starting t4");
        t4.start();
        System.out.println("Starting t5");
        t5.start();
//      
        t5.join();
        t4.join();

    }

}
xoefb8l8

xoefb8l82#

(我猜在这种情况下,“它没有工作”意味着程序挂起。请具体说明您看到的问题。)
有两个问题。一种是在每个线程中创建单独的对象。调用wait和notify的对象必须相同,等待的监视器是需要接收notify的监视器。在这段代码中,同步方法在调用方法的示例上使用内在锁。
在main方法中创建一次对象,每个线程需要引用同一个对象。
第二个问题,一旦你解决了第一个问题,将是一个竞赛条件。如果由一个线程执行的notify首先发生,那么当wait执行时,notify已经发生,并且wait将永远等待。
添加条件变量以记住是否发生了通知。
一般来说,模式是检查循环中的条件,请看这个问题:为什么我们必须使用“while”来检查竞争条件而不是“if”。post有一个使用变量查看是否发生了条件的示例,这里是

synchronized(obj)
{
    while (condition_not_matched)
    {
        obj.wait();
    }
    //continue
    dosomething();
}
rfbsl7qr

rfbsl7qr3#

这个代码对我有用我现在有了while循环

public class C {

int i = 34;
public synchronized void test() throws InterruptedException {
    System.out.println("car");
    while(i == 34) {
         wait();
    }

    notify();
    System.out.println("car");
}

public synchronized void Passagier() throws InterruptedException {
    i = 55;
    System.out.println("p");

    notify();

}

public static void main(String[] args)
        throws InterruptedException {

    C b = new C();
    Thread t4 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                b.Passagier();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });
    Thread t5 = new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                b.test();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }

    });

    t4.start();
    t5.start();
    t4.join();
    t5.join();
    }
   }

相关问题