04-传统线程同步通信技术
package cn.itcast.demo.thread; public class TradictionalThreadCommunication { // main 方法本身就是一个线程【当作是主线程,main 方法内的线程就是子线程】 public static void main(String[] args) { // 子线程 new Thread(new Runnable() { @Override public void run() { for (int i=1; i<=50; i++) { synchronized (TradictionalThreadCommunication.class) { for (int j=1; j<=10; j++) { System.out.println("sub thread sequece of " + j + ", loop thread sequece of " + i); } } } } }).start(); // 主线程 for (int i=1; i<=50; i++) { synchronized (TradictionalThreadCommunication.class) { for (int j=1; j<=10; j++) { System.out.println("main thread sequece of " + j + ", loop thread sequece of " + i); } } } } }
以上代码写的不好,下面是改进后的代码:把子线程和主线程的方法都放到同一个类中
package cn.itcast.demo.thread; public class TradictionalThreadCommunication { // main 方法本身就是一个线程【当作是主线程,main 方法内的线程就是子线程】 public static void main(String[] args) { final Business business = new Business(); // 子线程 new Thread(new Runnable() { @Override public void run() { for (int i=1; i<=50; i++) { business.sub(i); } } }).start(); // 主线程 for (int i=1; i<=50; i++) { business.main(i); } } } class Business { // 子线程 public synchronized void sub(int i) { for (int j=1; j<=10; j++) { System.out.println("sub thread sequece of " + j + ", loop thread sequece of " + i); } } // 主线程 public synchronized void main(int i) { for (int j=1; j<=100; j++) { System.out.println("main thread sequece of " + j + ", loop thread sequece of " + i); } } }
以上代码在控制台只打印了部分,看不出结果,解决方法:
右键--Run As--Run Configurations--Common--在File前面挑上复选框,路径指向磁盘的一个文件,比如 F:\1.txt--执行Run
执行完后,找到该文件,打开,里面就是全部的执行结果:
此时,发现结果可以实现了主线程和子线程的互斥,但结果是主线程全部执行完了之后采取执行子线程,但题目要求是主线程和子线程交替执行
改进:
package cn.itcast.demo.thread; public class TradictionalThreadCommunication { // main 方法本身就是一个线程【当作是主线程,main 方法内的线程就是子线程】 public static void main(String[] args) { final Business business = new Business(); // 子线程 new Thread(new Runnable() { @Override public void run() { for (int i=1; i<=50; i++) { business.sub(i); } } }).start(); // 主线程 for (int i=1; i<=50; i++) { business.main(i); } } } // 业务类 class Business { // 主线程和子线程交互执行的标识变量 private boolean beShouldSub = true; // 子线程 public synchronized void sub(int i) { // 不符合条件,让给主线程执行 while (!beShouldSub) { // 这里用if或while都可以,但是while更好,因为不需要main方法判断就已经执行,下面一样,可以防止“伪唤醒” try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 符合条件,子线程执行 for (int j=1; j<=10; j++) { System.out.println("sub thread sequece of " + j + ", loop thread sequece of " + i); } // 执行完之后,切换状态 beShouldSub = false; // 唤醒主线程,去执行 this.notify(); } // 主线程 public synchronized void main(int i) { // 不符合条件,子线程执行 while (beShouldSub) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 符合条件,主线程执行 for (int j=1; j<=100; j++) { System.out.println("main thread sequece of " + j + ", loop thread sequece of " + i); } // 执行完之后,切换状态 beShouldSub = true; // 唤醒子线程,去执行 this.notify(); } }