多线程之同步线程通信小例子

来源:互联网 发布:python编程工具下载 编辑:程序博客网 时间:2024/06/05 08:04

最近在学习多线程的时候,看到这样的一个问题:有两个线程,一个是子线程,一个是主线程,子线程运行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();    }}


0 0
原创粉丝点击