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

Java 使用wait()和notify()进行同步,java,multithreading,Java,Multithreading,我需要使用3个不同的线程打印以下图案,以便: 线程1打印“I” 线程2打印“爱” 线程3打印“地球” 使用wait()和notify()方法。 我从下面的代码开始,但似乎只打印了一次,因为它们都在每个循环的第一次迭代结束时等待 public class MultiThreading_2 { static volatile boolean flag=false; static volatile String word = "I"; public static void main(String

我需要使用3个不同的线程打印以下图案,以便:

线程1打印“I”

线程2打印“爱”

线程3打印“地球”

使用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)
                {

                for(int k=1;k<=2;k++) {
                        System.out.println("WORLD ");
                        word="I";
                        try {
                            m.wait();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }

                            m.notify();



                    }


                }

                }
                }



    };


    new Thread(a).start();
    Thread.sleep(100);
    new Thread(b).start();
    Thread.sleep(100);
    new Thread(c).start();

}


}
公共类多线程\u 2{
静态易失性布尔标志=false;
静态易失性字符串word=“I”;
公共静态void main(字符串[]args)引发InterruptedException{
多线程_2 m=新的多线程_2();
Runnable a=新的Runnable(){
公开募捐{
如果(字等于(“I”))
{
同步(m)
{

for(int i=1;i我已修复了您的代码。您已将“m.notify()”放在“m.wait()”之后,因此它们都在互相等待。我轻轻地将其移动到“m.wait()”之前,并将for循环转换为无尽的while循环,以使线程永远运行

更新1

我已经更新了代码,这样线程就可以编写三次文本

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() {

                for (int i = 0; i < 3; i++) {
                    synchronized (m) {
                        if (word.equals("I")) {
                            System.out.print("I ");
                            word = "LOVE";

                            m.notify();
                            try {
                                m.wait();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        } else {
                            i--;
                        }

                    }

                }
            }

        };

        Runnable b = new Runnable() {

            public void run() {

                for (int i = 0; i < 3; i++) {
                    synchronized (m) {
                        if (word.equals("LOVE")) {
                            System.out.print("LOVE ");
                            word = "WORLD";
                            m.notify();
                            try {
                                m.wait();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                        } else {
                            i--;
                        }

                    }

                }
            }

        };

        Runnable c = new Runnable() {

            public void run() {

                for (int i = 0; i < 3; i++) {
                    synchronized (m) {
                        if (word.equals("WORLD")) {
                            System.out.println("WORLD ");
                            word = "I";
                            m.notify();
                            try {
                                m.wait();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }

                        } else {
                            i--;
                        }
                    }

                }

            }

        };

        new Thread(a).start();
        Thread.sleep(100);
        new Thread(b).start();
        Thread.sleep(100);
        new Thread(c).start();

    }

}
公共类多线程\u 2{
静态易失性布尔标志=false;
静态易失性字符串word=“I”;
公共静态void main(字符串[]args)引发InterruptedException{
多线程_2 m=新的多线程_2();
Runnable a=新的Runnable(){
公开募捐{
对于(int i=0;i<3;i++){
同步(m){
如果(字等于(“I”)){
系统输出打印(“I”);
word=“爱”;
m、 通知();
试一试{
m、 等待();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}否则{
我--;
}
}
}
}
};
Runnable b=新的Runnable(){
公开募捐{
对于(int i=0;i<3;i++){
同步(m){
如果(单词等于(“爱”)){
系统输出打印(“爱”);
word=“世界”;
m、 通知();
试一试{
m、 等待();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}否则{
我--;
}
}
}
}
};
Runnable c=新的Runnable(){
公开募捐{
对于(int i=0;i<3;i++){
同步(m){
如果(单词等于(“世界”)){
System.out.println(“世界”);
word=“I”;
m、 通知();
试一试{
m、 等待();
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}否则{
我--;
}
}
}
}
};
新线程(a.start();
睡眠(100);
新线程(b.start();
睡眠(100);
新线程(c.start();
}
}
Object.notify()
选择一个随机线程来唤醒。由于在两次启动之间出现休眠,您的代码只工作一次,您人为地确保了预期的执行顺序

您应该使用
notifyAll()
,唤醒所有线程,因此,线程应该在循环中等待()
,直到轮到它们:

Runnable a = new Runnable() {
  public void run() {
    synchronized (m) {
      for (int i = 1; i <= 2; i++) {
        while(!word.equals("I"))
          try{
            m.wait();
          }
          catch(InterruptedException ie){
            ie.printStackTrace();
          }
        System.out.print("I ");
        word = "LOVE";
        m.notifyAll();
      }
    }
  }
};

Runnable b = new Runnable() {
  public void run() {
    synchronized (m) {
      for (int i = 1; i <= 2; i++) {
        while(!word.equals("LOVE"))
          try{
            m.wait();
          }
          catch(InterruptedException ie){
            ie.printStackTrace();
          }
        System.out.print("LOVE ");
        word = "WORLD";
        m.notifyAll();
      }
    }
  }
};

Runnable c = new Runnable() {
  public void run() {
    synchronized (m) {
      for (int i = 1; i <= 2; i++) {
        while(!word.equals("WORLD"))
          try{
            m.wait();
          }
          catch(InterruptedException ie){
            ie.printStackTrace();
          }
        System.out.println("WORLD ");
        word = "I";
        m.notifyAll();
      }
    }
  }
};

new Thread(a).start();
new Thread(b).start();
new Thread(c).start();
Runnable a=new Runnable(){
公开募捐{
同步(m){

对于(int i=1;i代码不存在)compile@JohnSnowDoesNotKnowNothing编辑请检查注意:此练习可能会教您一些有关如何同步线程的知识,但这是一个非常糟糕的示例,说明何时或为什么要同步线程。同步线程是一个必要的缺点。通常,您应该尽可能不做任何事情使程序工作所必需的。通常,如果您希望程序按特定顺序执行某些操作(例如,打印“I”,然后打印“Love”,然后打印“Earth”)那么最好的方法就是在同一个线程中完成所有这些事情。是的,但是如果每个结果都来自三个不同线程上运行的三个不同应用程序呢?@Ghostider,这是一个开放性的问题。为什么这些“应用程序”运行在不同的线程上?(可能是一个很好的原因,也可能是设计不好的结果)为什么订单很重要?(好/坏原因同上)。如果有充分的理由,那么我可能会将结果放入一个列表中,让一个线程对列表进行排序,然后在其他线程完成工作后输出。@Bahadir Tasdemir感谢修复。。正如我试图理解的,m.wait()是否会在m.notify()之后执行。您能解释一下wait()的流程吗和notify()在这里?不客气。使用notify()可以让线程通知它已完成其工作。使用wait()可以让线程收到通知。当调用wait before notify时,对于所有线程,它们都会进入waiying状态。很简单,没有任何线程通知一个线程,它们都是wa
Runnable a = new Runnable() {
  public void run() {
    synchronized (m) {
      for (int i = 1; i <= 2; i++) {
        while(!word.equals("I"))
          try{
            m.wait();
          }
          catch(InterruptedException ie){
            ie.printStackTrace();
          }
        System.out.print("I ");
        word = "LOVE";
        m.notifyAll();
      }
    }
  }
};

Runnable b = new Runnable() {
  public void run() {
    synchronized (m) {
      for (int i = 1; i <= 2; i++) {
        while(!word.equals("LOVE"))
          try{
            m.wait();
          }
          catch(InterruptedException ie){
            ie.printStackTrace();
          }
        System.out.print("LOVE ");
        word = "WORLD";
        m.notifyAll();
      }
    }
  }
};

Runnable c = new Runnable() {
  public void run() {
    synchronized (m) {
      for (int i = 1; i <= 2; i++) {
        while(!word.equals("WORLD"))
          try{
            m.wait();
          }
          catch(InterruptedException ie){
            ie.printStackTrace();
          }
        System.out.println("WORLD ");
        word = "I";
        m.notifyAll();
      }
    }
  }
};

new Thread(a).start();
new Thread(b).start();
new Thread(c).start();