多线程的控制(等待唤醒机制)

1、两个线程

package com.zy.demo09;
//单例模式
public class A {
    private A() {
        
    }
    private static A a=new A();
    public static A getA(){
        return a;
    }

}
package com.zy.demo09;
public class People {
    static String name;
    static String sex;

}
package com.zy.demo09;
public class MyRunnable01 implements Runnable{
    @Override
    public void run() {
        int a=0;
        while (true) {
            synchronized (A.getA()) {                
                a++;
                if (a%2==0) {
                    People.name="小明";
                    People.sex="男";
                } else {
                    People.name="小红";
                    People.sex="女";
                    
                }            
                //等待唤醒要明确锁对象是谁(先唤醒再等待)
                A.getA().notify();//唤醒对方
                try {
                    A.getA().wait();//让自己等待----失去了cpu的执行权了
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
            }
    
        }
    }
}
package com.zy.demo09;
public class MyRunnbale02 implements Runnable{
    @Override
    public void run() {
        while (true) {
            synchronized (A.getA()) {
                System.out.println(People.name);
                System.out.println(People.sex);                
                //等待唤醒要明确锁对象是谁
                A.getA().notify();//唤醒对方
                try {
                    A.getA().wait();//让自己等待----失去了cpu的执行权了
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }            
            }        
        }        
    }
}
package com.zy.demo09;
public class Test {
    public static void main(String[] args) {    
        //线程任性
        Thread thread1 = new Thread(new MyRunnable01());
        Thread thread2 = new Thread(new MyRunnbale02());
        thread1.start();
        thread2.start();
        //等待唤醒-----控制线程    
        //等待唤醒的基础条件------在线程同步环境下
                //要明确所属的锁对象是谁    synchronized (A.getA()) {}
            /*   
                //等待唤醒要明确锁对象是谁
                A.getA().notify();//唤醒对方
                try {
                A.getA().wait();//让自己等待----失去了cpu的执行权了
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }*/
    }
}

运行结果:虚拟灯不灭,一直输出按小红 女和小明 男的格式输出,不会出现性别错乱的情况

2、三个线程(one by one)

按红黄蓝的顺序输出

package com.zy.exercise;
public class A {
    private A() {    
    }
    static int flag = 1;//flag为1执行第一个线程,为2执行第二个线程,为3执行第三个线程
    private static A a=new A();
    public static A getA(){
        return a;
    }

}
package com.zy.exercise;
public class MyRunnable01 implements Runnable{
    @Override
    public void run() {
        while(true){
            synchronized (A.getA()) {            
                   while(A.flag == 1) {
                       System.out.println("红");
                       A.flag = 2;
                   }
                   A.getA().notify();
                   try {
                       A.getA().wait();
                   }catch(InterruptedException e) {
                       e.printStackTrace();
                   }
            }
        }
        
    }
    

}
package com.zy.exercise;

public class MyRunnable02 implements Runnable{

    @Override
    public void run() {
        while(true){
            synchronized (A.getA()) {
                while(A.flag == 2) {
                    System.out.println("黄");
                    A.flag = 3;
                }
                A.getA().notify();
                try {
                    A.getA().wait();
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }
                
                 }
            }
        
    }

}
package com.zy.exercise;

public class MyRunnable03 implements Runnable{

    @Override
    public void run() {
        while(true){
            synchronized (A.getA()) {
                  
                while(A.flag == 3) {
                    System.out.println("蓝");
                    A.flag=1;
                }
                A.getA().notify();
                try {
                    A.getA().wait();
                }catch(InterruptedException e) {
                    e.printStackTrace();
                }
       
            }

            }
        
    }

}
package com.zy.exercise;

public class Test {

    public static void main(String[] args) throws Exception {
        Thread thread1 = new Thread(new MyRunnable01());
        Thread thread2 = new Thread(new MyRunnable02());
        Thread thread3 = new Thread(new MyRunnable03());
        thread1.start();
        thread2.start();
        thread3.start();
 
   }
}

运行结果

虚拟灯不灭一直按红黄蓝的顺序输出

原文地址:https://www.cnblogs.com/qfdy123/p/11122839.html