多线程的控制(等待唤醒机制)
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(); }
}
运行结果
虚拟灯不灭一直按红黄蓝的顺序输出