猿问

使用wait()和notify()进行同步

我需要使用3个不同的线程来打印以下模式:


线程1打印“ I”


线程2打印“ LOVE”


线程3打印“ EARTH”


I LOVE EARTH

I LOVE EARTH

I LOVE EARTH

使用wait()和notify()方法。我从下面的代码开始,但是似乎它们只打印一次,因为它们都在每个循环的第一次迭代结束时等待。


public class MultiThreading_2 {

static volatile boolean flag=false;

static volatile String  word = "I";



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


    MultiThreading_2 m = new MultiThreading_2();



    Runnable a = new Runnable() {


        public void run() {

            if(word.equals("I"))

            {

                synchronized(m)

                {

                for(int i=1;i<=2;i++) {


                    if(word.equals("I"))    {   

                        System.out.println("I ");

                        word="LOVE";


                        try {

                            m.wait();

                        } catch (InterruptedException e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                        }

                    }

                    m.notify();


                }


                }

                }

        }



    };


    Runnable b = new Runnable() {


        public void run() {


            if(word.equals("LOVE"))

            {

                synchronized(m)

                {


                for(int j=1;j<=2;j++) {


                    if(word.equals("LOVE")) {

                        System.out.println("LOVE ");

                        word="WORLD";

                        try {

                            m.wait();

                        } catch (InterruptedException e) {

                            // TODO Auto-generated catch block

                            e.printStackTrace();

                        }

                        m.notify();



                    }


                }



                }

                }

        }




    };


    Runnable c = new Runnable() {


        public void run() {


            if(word.equals("WORLD"))

            {

                synchronized(m)

                {


   

有人可以解释如何解决这个问题吗?


喵喔喔
浏览 136回答 2
2回答

慕运维8079593

我已经修复了您的代码。您已将“ m.notify()”放在“ m.wait()”之后,因此它们都互相等待。我在“ m.wait()”之前轻轻移动了它,并将for循环转换为无尽的while循环,以使线程永远运行。更新1我已经更新了代码,以便线程将文本写入3次。public class MultiThreading_2 {&nbsp; &nbsp; static volatile boolean flag = false;&nbsp; &nbsp; static volatile String word = "I";&nbsp; &nbsp; public static void main(String[] args) throws InterruptedException {&nbsp; &nbsp; &nbsp; &nbsp; MultiThreading_2 m = new MultiThreading_2();&nbsp; &nbsp; &nbsp; &nbsp; Runnable a = new Runnable() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 3; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (m) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (word.equals("I")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.print("I ");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; word = "LOVE";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.notify();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; Runnable b = new Runnable() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 3; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (m) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (word.equals("LOVE")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.print("LOVE ");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; word = "WORLD";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.notify();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; Runnable c = new Runnable() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void run() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 3; i++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (m) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (word.equals("WORLD")) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("WORLD ");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; word = "I";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.notify();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (InterruptedException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // TODO Auto-generated catch block&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; e.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i--;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; new Thread(a).start();&nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep(100);&nbsp; &nbsp; &nbsp; &nbsp; new Thread(b).start();&nbsp; &nbsp; &nbsp; &nbsp; Thread.sleep(100);&nbsp; &nbsp; &nbsp; &nbsp; new Thread(c).start();&nbsp; &nbsp; }}

沧海一幻觉

Object.notify()选择一个随机线程唤醒。由于两次启动之间的睡眠,您的代码只能工作一次,因此您可以人为地确保预期的执行顺序。您应该使用notifyAll(),唤醒所有线程,因此,线程应该wait()循环循环,直到轮到为止:Runnable a = new Runnable() {&nbsp; public void run() {&nbsp; &nbsp; synchronized (m) {&nbsp; &nbsp; &nbsp; for (int i = 1; i <= 2; i++) {&nbsp; &nbsp; &nbsp; &nbsp; while(!word.equals("I"))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch(InterruptedException ie){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.print("I ");&nbsp; &nbsp; &nbsp; &nbsp; word = "LOVE";&nbsp; &nbsp; &nbsp; &nbsp; m.notifyAll();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }};Runnable b = new Runnable() {&nbsp; public void run() {&nbsp; &nbsp; synchronized (m) {&nbsp; &nbsp; &nbsp; for (int i = 1; i <= 2; i++) {&nbsp; &nbsp; &nbsp; &nbsp; while(!word.equals("LOVE"))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch(InterruptedException ie){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.print("LOVE ");&nbsp; &nbsp; &nbsp; &nbsp; word = "WORLD";&nbsp; &nbsp; &nbsp; &nbsp; m.notifyAll();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }};Runnable c = new Runnable() {&nbsp; public void run() {&nbsp; &nbsp; synchronized (m) {&nbsp; &nbsp; &nbsp; for (int i = 1; i <= 2; i++) {&nbsp; &nbsp; &nbsp; &nbsp; while(!word.equals("WORLD"))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m.wait();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch(InterruptedException ie){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ie.printStackTrace();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("WORLD ");&nbsp; &nbsp; &nbsp; &nbsp; word = "I";&nbsp; &nbsp; &nbsp; &nbsp; m.notifyAll();&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }};new Thread(a).start();new Thread(b).start();new Thread(c).start();在if从一开始就已经被删除,在真正的并发执行难保有在预期值word。然后,其中一个线程抓住该锁,检查是否word是自己的那个线程,或者开始等待,或者打印其文本和步骤word以进入下一阶段,从而唤醒其他线程(两个线程都带有notifyAll())。然后它要么退出,要么继续wait()再次。这是重要的部分:我想尽可能少地修改您的代码,以便所有事情都在同步块内发生,这意味着线程仅在其他两个正在等待或完成时才可以运行。对于此锁步,它可以工作,但通常而言,同步块应该位于for循环内,可能是两个单独的块,一个围绕equals-wait循环,另一个围绕set + notifyAll语句。
随时随地看视频慕课网APP

相关分类

Java
我要回答