最近在学习多线程的时候,看到这样的一个问题:有两个线程,一个是子线程,一个是主线程,子线程运行10次,接着主线程运行20次,接着子线程运行10,主线程运行20次,依次交替循环20次。刚开始看到这个问题的时候,很是茫然。后来分析一下,子线程和主线程交替运行,这是一个线程在执行的时候,另一个线程在等待状态,当在执行的线程执行完之后,唤醒另外一个线程,这样交替进行。线程在执行的地方是要加锁的。但是,在什么样的场景下会出现这样的情形呢?多线程在同步访问同一个资源的时候。于是写出来的代码如下所示:
package com.zkn.newlearn.thread; /** * Created by zkn on 2016/11/14. * 传统的同步通信技术 * 需求描述: * 子线程先运行10次,接着主线程运行20次, * 接着子线程运行10次,依次交替反复20次 * 关键点:共同数据要放到一个类上。 * 难点:可能想不用操作一个共同的对象来解决。 * 多线程访问操作共同资源的时候,要在资源的类上进行操作。 */ public class ThreadSynchronousCommunicationTest01 { public static void main(String[] args){ //确保多线程对共同资源的操作,是操作在资源类上。 SynchronousCommunication synchronousCommunication = new SynchronousCommunication(); new Thread( new Runnable() { @Override public void run() { for(int i=0;i<20;i++){ synchronousCommunication.sub(i); } } } ).start(); for(int i=0;i<20;i++){ synchronousCommunication.main(i); } } } /** * 通信类 */ class SynchronousCommunication{ /** * 线程执行的标记 */ private boolean flag = true; public synchronized void sub(int i){ //这里要用while,防止线程被假唤醒 //如果flag是false,说明主线程在执行,所以子线程要进入等待状态 while(!flag){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int j=0;j<10;j++){ System.out.println("子线程第"+i+"遍运行,运行到第"+j+"次"); } //子线程执行完之后,要改变执行标记 flag = false; //唤醒休眠中的线程(即这里的主线程) this.notifyAll(); } public synchronized void main(int i){ //这里要用while,防止线程被假唤醒 //如果flag是false,说明子线程在执行,所以主线程要进入等待状态 while (flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } for(int j=0;j<20;j++){ System.out.println("主线程第"+i+"遍运行,运行到第"+j+"次"); } //主线程执行完之后,要改变执行标记 flag = true; //唤醒休眠中的线程(即这里的子线程) this.notifyAll(); } }
时间: 2024-08-01 21:14:10