Java Lock锁多线程中实现流水线任务

  下面程序代码通过使用Lock锁执行简单的流水线任务:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author lzq
 * @data 2020/4/29 0029 - 下午 9:48
 */
public class TestLock {
  public static void main(String[] args) {
    DataSource dataSource=new DataSource();
    new Thread(() -> {
      for (int i=0;i<10;i++){
        dataSource.a();
      }
    },"A").start();

    new Thread(() -> {
      for (int i=0;i<10;i++){
        dataSource.b();
      }
    },"B").start();

    new Thread(() -> {
      for (int i=0;i<10;i++){
        dataSource.c();
      }
    },"C").start();
  }
}

class DataSource{
  private int x=1;
  private Lock lock=new ReentrantLock();
  private Condition condition1=lock.newCondition();
  private Condition condition2=lock.newCondition();
  private Condition condition3=lock.newCondition();

  public void a(){
    lock.lock();
    try {
      while(x!=1){
        condition1.await();
      }
      System.out.println(Thread.currentThread().getName()+":aaa");
      x=2;
      condition2.signal();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
  public void b(){
    lock.lock();
    try {
      while(x!=2){
        condition2.await();
      }
      System.out.println(Thread.currentThread().getName()+":bbb");
      x=3;
      condition3.signal();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
  public void c(){
    lock.lock();
    try {
      while(x!=3){
        condition3.await();
      }
      System.out.println(Thread.currentThread().getName()+":ccc");
      x=1;
      condition1.signal();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      lock.unlock();
    }
  }
}

    执行结果如下:

对于上面代码简单分析:代码中包含简单的生产者消费者流程和Lock实现三部曲,即重复判断条件,执行逻辑,唤醒其他线程和产生锁,加锁,解锁。注意这里一点,条件判断一定要重复判断,不然可能会导致线程假醒影响结果。

因为当线程处于等待状态时,线程会释放资源,等到被唤醒的时候,从上次await的地方醒来继续执行,这时条件判断成立,执行await,其他线程再修改条件使得本线程被唤醒,此时本线程不会继续判断,而是继续执行,如果使用循环判断就能检验出条件被修改。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 对Python多线程读写文件加锁的实例详解

    Python的多线程在io方面比单线程还是有优势,但是在多线程开发时,少不了对文件的读写操作.在管理多个线程对同一文件的读写操作时,就少不了文件锁了. 使用fcntl 在linux下,python的标准库有现成的文件锁,来自于fcntl模块.这个模块提供了unix系统fcntl()和ioctl()的接口. 对于文件锁的操作,主要需要使用 fcntl.flock(fd, operation)这个函数. 其中,参数 fd 表示文件描述符:参数 operation 指定要进行的锁操作,该参数的取值有如

  • C++多线程中的锁和条件变量使用教程

    在做多线程编程时,有两个场景我们都会遇到: 多线程访问共享资源,需要用到锁: 多线程间的状态同步,这个可用的机制很多,条件变量是广泛使用的一种. 今天我用一个简单的例子来给大家介绍下锁和条件变量的使用. 代码使用C++11 示例代码 #include <iostream> #include <mutex> #include <thread> #include <condition_variable> std::mutex g_mutex; // 用到的全局锁

  • Python利用多线程同步锁实现多窗口订票系统(推荐)

    利用Python实现多窗口订票系统,利用 threading.Lock() 避免出现一票多卖,无票也卖的情况,并规范化输出情况. 代码: import threading import time tickets, lock = 20, threading.Lock() class TicketWindows(threading.Thread): def __init__(self, window_name): threading.Thread.__init__(self) self.window

  • Python全局锁中如何合理运用多线程(多进程)

    Python全局锁 (1)全局锁导致的问题 全局锁的英文简称是GIL,全称是Global Interpreter Lock(全局解释器锁),来源是python设计之初的考虑,为了数据安全所做的决定,每个线程在执行时候都需要先获取GIL,保证同一时刻只有一个线程可以执行代码,即同一时刻只有一个线程使用CPU,也就是说多线程并不是真正意义上的同时执行. 每个CPU在同一时间只能执行一个线程(在单核CPU下的多线程其实都只是并发,不是并行,并发和并行从宏观上来讲都是同时处理多路请求的概念.但并发和并行

  • 对python多线程中Lock()与RLock()锁详解

    资源总是有限的,程序运行如果对同一个对象进行操作,则有可能造成资源的争用,甚至导致死锁 也可能导致读写混乱 锁提供如下方法: 1.Lock.acquire([blocking]) 2.Lock.release() 3.threading.Lock() 加载线程的锁对象,是一个基本的锁对象,一次只能一个锁定,其余锁请求,需等待锁释放后才能获取 4.threading.RLock() 多重锁,在同一线程中可用被多次acquire.如果使用RLock,那么acquire和release必须成对出现,

  • Python多线程中阻塞(join)与锁(Lock)使用误区解析

    关于阻塞主线程 join的错误用法 Thread.join() 作用为阻塞主线程,即在子线程未返回的时候,主线程等待其返回然后再继续执行. join不能与start在循环里连用 以下为错误代码,代码创建了5个线程,然后用一个循环激活线程,激活之后令其阻塞主线程. threads = [Thread() for i in range(5)] for thread in threads: thread.start() thread.join() 执行过程: 1. 第一次循环中,主线程通过start函

  • 对python多线程中互斥锁Threading.Lock的简单应用详解

    一.线程共享进程资源 每个线程互相独立,相互之间没有任何关系,但是在同一个进程中的资源,线程是共享的,如果不进行资源的合理分配,对数据造成破坏,使得线程运行的结果不可预期.这种现象称为"线程不安全". 实例如下: #-*- coding: utf-8 -*- import threading import time def test_xc(): f = open("test.txt","a") f.write("test_dxc&quo

  • python多线程高级锁condition简单用法示例

    本文实例讲述了python多线程高级锁condition简单用法.分享给大家供大家参考,具体如下: 多线程编程中如果使用Condition对象代替lock, 能够实现在某个事件触发后才处理数据, condition中含有的方法: - wait:线程挂起,收到notify通知后继续运行 - notify:通知其他线程, 解除其它线程的wai状态 - notifyAll(): 通知所有线程 - acquire和release: 获得锁和解除锁, 与lock类似, - enter和exit使得对象支持

  • Java Lock锁多线程中实现流水线任务

    下面程序代码通过使用Lock锁执行简单的流水线任务: import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @author lzq * @data 2020/4/29 0029 - 下午 9:48 */ public class TestLock { public stat

  • 浅析JAVA Lock锁原理

    同样是锁,先说说synchronized和lock的区别: synchronized是java关键字,是用c++实现的:而lock是用java类,用java可以实现 synchronized可以锁住代码块,对象和类,但是线程从开始获取锁之后开发者不能进行控制和了解:lock则用起来非常灵活,提供了许多api可以让开发者去控制加锁和释放锁等等. 写个Demo static Lock lock = new ReentrantLock();public static void main(String[

  • Java多线程中Lock锁的使用小结

    Lock基本使用 Lock它是java.util.concurrent.locks下的一个接口,它也是用来处理线程同步问题的. public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void

  • 教你Java中的Lock锁底层AQS到底是如何实现的

    目录 前言 加锁 释放锁 总结 前言 相信大家对Java中的Lock锁应该不会陌生,比如ReentrantLock,锁主要是用来解决解决多线程运行访问共享资源时的线程安全问题.那你是不是很好奇,这些Lock锁api是如何实现的呢?本文就是来探讨一下这些Lock锁底层的AQS(AbstractQueuedSynchronizer)到底是如何实现的. 本文是基于ReentrantLock来讲解,ReentrantLock加锁只是对AQS的api的调用,底层的锁的状态(state)和其他线程等待(No

  • Java多线程中Lock锁的使用总结

    多核时代 摩尔定律告诉我们:当价格不变时,集成电路上可容纳的晶体管数目,约每隔18个月便会增加一倍,性能也将提升一倍.换言之,每一美元所能买到的电脑性能,将每隔18个月翻两倍以上.然而最近摩尔定律似乎遇到了麻烦,目前微处理器的集成度似乎到了极限,在目前的制造工艺和体系架构下很难再提高单个处理器的速度了,否则它就被烧坏了.所以现在的芯片制造商改变了策略,转而在一个电路板上集成更多的处理器,也就是我们现在常见的多核处理器. 这就给软件行业带来麻烦(也可以说带来机会,比如说就业机会,呵呵).原来的情况

  • Java并发系列之JUC中的Lock锁与synchronized同步代码块问题

    目录 一.Lock锁 二.锁的底层 三.案例 案例一:传统的synchronized实现 案例二:Lock锁的实现 四.Lock锁和synchronized的区别 写在前边: 在Java服务端中,会常常遇到并发的场景,以下我使用两个售票的案例实现传统的Lock锁与synchronized加锁解决线程安全问题. 本章代码:Gitee: juc.demo 一.Lock锁 ReentrantLock类: 可重用锁(公平锁|非公平锁) ReentrantReadWriteLock.ReadLock:读锁

  • Java多线程中的wait/notify通信模式实例详解

    前言 最近在看一些JUC下的源码,更加意识到想要学好Java多线程,基础是关键,比如想要学好ReentranLock源码,就得掌握好AQS源码,而AQS源码中又有很多Java多线程经典的一些应用:再比如看了线程池的核心源码实现,又学到了很多核心实现,其实这些都可以提出来慢慢消化并变成自己的知识点,今天这个Java等待/通知模式其实是Thread.join()实现的关键,还有线程池工作线程中线程跟线程之间的通信的核心所在,故在此为了加深理解,做此记录! 参考资料<Java并发编程艺术>(电子PD

随机推荐