以下讲解Lock线程同步通信,也是比synchronized强大的一个功能点

先看一个常规的案例:

用户类

public class Person {
    public void eat(){
        for(int i=0;i<3;i++){
            System.out.println("eat...");
        }
    }

    public void drink(){
        for(int i=0;i<3;i++){
            System.out.println("drink...");
        }
    }

    public void play(){
        for(int i=0;i<3;i++){
            System.out.println("play...");
        }
    }
}
public class LockConditionTest {
    public static void main(String[] args) {
        final Person person = new Person();
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for(int i=0;i<5;i++){
                            person.eat();
                        }
                    }
                }
                )
        .start();

        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for(int i=0;i<5;i++){
                            person.drink();
                        }
                    }
                }
                )
        .start();

        for(int i=0;i<10;i++){
            person.play();
        }
    }
}

结果输出:

eat...
eat...
play...
play...
play...
play...
play...
play...
play...
drink...
drink...
play...
play...
play...
play...

以上案例为传统线程调用,打印的结果也是有cpu随机调度输出

现在的需求是:person 吃喝玩方法要有顺序性调用,阻止cpu随机调度输出

参考以下案例(加入Lock实现同步通信):

public class Person {

    Lock lock = new ReentrantLock();
    Condition condition1 = lock.newCondition();
    Condition condition2 = lock.newCondition();
    Condition condition3 = lock.newCondition();
    private int shouldSub = 1;

    public void eat(){
        lock.lock();
        try{
            while(shouldSub!=1){      //是1的时候执行  不是1的时候等待
                try {
                    condition1.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for(int i=0;i<3;i++){
                System.out.println("eat...");
            }
            shouldSub=2;
            condition2.signal();    // 1 执行完之后 通知2执行
         }finally{
             System.out.println("=======================");
             lock.unlock();
         }
    }

    public void drink(){
        lock.lock();
        try{
            while(shouldSub!=2){ //是2的时候执行  不是2的时候等待
                try {
                    condition2.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for(int i=0;i<3;i++){
                System.out.println("drink...");
            }
            shouldSub = 3;
            condition3.signal();// 2 执行完之后 通知3执行
         }finally{
             System.out.println("=======================");
             lock.unlock();
         }
    }

    public void play(){
        lock.lock();
        try{
            while(shouldSub!=3){    //是3的时候执行  不是3的时候等待
                try {
                    condition3.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for(int i=0;i<3;i++){
                System.out.println("play...");
            }
            shouldSub = 1;
            condition1.signal();// 3 执行完之后 通知1执行
        }finally{
            System.out.println("=======================");
             lock.unlock();
         }
    }
}
public class LockConditionTest {
    public static void main(String[] args) {
        final Person person = new Person();
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for(int i=0;i<5;i++){
                            person.eat();
                        }
                    }
                }
                )
        .start();

        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for(int i=0;i<5;i++){
                            person.drink();
                        }
                    }
                }
                )
        .start();

        for(int i=0;i<5;i++){
            person.play();
        }
    }
}

结果输出:

eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================
eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================
eat...
eat...
eat...
=======================
drink...
drink...
drink...
=======================
play...
play...
play...
=======================

JAVA线程同步通信的更多相关文章

  1. Java线程并发:知识点

    Java线程并发:知识点   发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用.   逃逸:在对象尚未准备 ...

  2. Java线程的概念

    1.      计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...

  3. Java 线程池框架核心代码分析--转

    原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...

  4. 细说进程五种状态的生老病死——双胞胎兄弟Java线程

    java线程的五种状态其实要真正高清,只需要明白计算机操作系统中进程的知识,原理都是相同的. 系统根据PCB结构中的状态值控制进程. 单CPU系统中,任一时刻处于执行状态的进程只有一个. 进程的五种状 ...

  5. 【转载】 Java线程面试题 Top 50

    Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...

  6. 第24章 java线程(3)-线程的生命周期

    java线程(3)-线程的生命周期 1.两种生命周期流转图 ** 生命周期:**一个事物冲从出生的那一刻开始到最终死亡中间的过程 在事物的漫长的生命周期过程中,总会经历不同的状态(婴儿状态/青少年状态 ...

  7. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  8. 第22章 java线程(2)-线程同步

    java线程(2)-线程同步 本节主要是在前面吃苹果的基础上发现问题,然后提出三种解决方式 1.线程不安全问题 什么叫线程不安全呢 即当多线程并发访问同一个资源对象的时候,可能出现不安全的问题 对于前 ...

  9. 第21章 java线程(1)-线程初步

    java线程(1)-线程初步 1.并行和并发 并行和并发是即相似又有区别: 并行:指两个或者多个事件在同一时刻点发生. 并发:指两个或多个事件在同一时间段内发生 在操作系统中,并发性是指在一段事件内宏 ...

随机推荐

  1. vue-fiters过滤器的使用

    1.定义过滤器 2.使用过滤器 ...... <el-table-column prop="user_gender" align="center" lab ...

  2. 在Eclipse-jee-neon中配置springsource-tool-suite

    今天为大家展示如何在Eclipse-jee-neon中配置spring的插件(springsource-tool-suit): 打开Eclipse,查看自己的版本. Help –> About ...

  3. .net 项目中应用Web Services(vs2012)

    一.在asp.net项目中添加Web services1.新建一个asp.net项目(目前尚未验证是否可以在MVC项目中添加)2.在项目名上右击,选择添加→新建项→Web服务,输好名称后确定即可 二. ...

  4. Tree命令安装和使用

    Tree命令简介 tree是一种递归目录列表命令,产生一个深度缩进列表文件,这是彩色的ALA dircolors如果ls_colors设置环境变量和输出是TTY.树已经被移植和报道以下操作系统下工作: ...

  5. android 打卡 虚拟定位 sqlite

    1.使用android5.1模拟器 android5.1模拟器使用数据库管理参数文件,6.0及以后的版本使用xml文件管理 2.使用sqlite修改配置文件 3.修改secure库中的android_ ...

  6. JS合并两个函数

    /** * 合并两个函数 * @param functionA 先执行 * @param functionB 执行完 functionA 后返回 * @returns {*} */ function ...

  7. CSS多列布局(栅格布局)

    一.多列布局 CSS3 可以将文本内容设计成像报纸一样的多列布局,如下实例: 代码如下(具体的解释也在代码中)浏览器支持表格中的数字表示支持该方法的第一个浏览器的版本号. 紧跟在数字后面的 -webk ...

  8. git本地创建一个分支并上传到远程服务器上

    git branch 查看分支 新建分支:git checkout -b dev 把新建的本地分支push到远程服务器 git push origin 本地名字:外地名字 删除远程分支 git pus ...

  9. 使用Windows service创建一个简单的定时器

    一.需求 我们有时候可能会想要做一些定时任务,例如每隔一段时间去访问某个网站,或者下载一些东西到我们服务器上等等之类的事情,这时候windows service 是一个不错的选择. 二.实现 1.打开 ...

  10. Promise和async/await

    1.promise对象 promise 对象有三种状态:pending(进行中).fulfilled(已成功)和 rejected(已失败).promise 对象的状态改变,只有两种可能:从 pend ...