重入锁(ReentrantLock)、重入读写锁(ReentrantReadWriteLock)、线程通信(Condition)

什么是 ReentrantLock? 是 Java 中提供的一个可重入锁,它是包中的一个类。与关键字相比,提供了更多的功能,允许更加灵活的控制线程同步行为。 阅读详情


1.使用重入锁完成的“生产-消费”模型:

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

class Account {
    private static int commonIndex = 5;
    private static Lock indexLock = new ReentrantLock();
    private static Condition canPull = indexLock.newCondition();
    private static Condition needPush = indexLock.newCondition();

    // 多线程索取
    public int pull() {
        int index = 0;
        indexLock.lock();
        try {
            while (commonIndex < 1) {// 判断数据是否符合条件,没有则继续等待并通知补充!
                System.out.println("数量小于1,不够了,请补充...");
                needPush.signalAll();// 数量不够了需要放入,发出需要补充信号
                canPull.await();//等待可以拉取的通知
                System.out.println("收到拉取通知,继续拉取...");
            }
            index = commonIndex;
            Thread.sleep(200); // 用于测试是否会出现取出相同的数字来,(结果:加锁后不会有线程问题)
            commonIndex--;
        } catch (Exception e) {} finally {
            indexLock.unlock();
        }
        return index;
    }

    // 单线成维护
    public void push() {
        indexLock.lock();
        try {
            while (commonIndex <= 0) {
                commonIndex += 3;//以此补充3个
                canPull.signalAll();//通知:可以拉取了...
                System.out.println("报告补充完毕!继续等待补充通知...");
                needPush.await();//等待
            }
        } catch (Exception e) {} finally {
            indexLock.unlock();
        }
    }
}

public class Test {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(100);
        // 索取
        for (int i = 0; i < 10; i++) {
            threadPool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(new Account().pull());
                }
            });
        }
        // 维护,这里也可以用多个线程,但是同步判断条件commonIndex <= 0,
        // 会使得多线程无意义,即只有第一个线程会补充,后续补充线程发现 >0 后不再补充
        threadPool.execute(new Runnable() {
            @Override
            public void run() {
                new Account().push();
            }
        });
        // 关闭线程池
        threadPool.shutdown();
    }
}

运行结果:

5
4
3
2
1
数量小于1,不够了,请补充...
数量小于1,不够了,请补充...
数量小于1,不够了,请补充...
数量小于1,不够了,请补充...
数量小于1,不够了,请补充...
报告补充完毕!继续等待补充通知...
收到拉取通知,继续拉取...
3
收到拉取通知,继续拉取...
2
收到拉取通知,继续拉取...
1
收到拉取通知,继续拉取...
数量小于1,不够了,请补充...
收到拉取通知,继续拉取...
数量小于1,不够了,请补充...
报告补充完毕!继续等待补充通知...
收到拉取通知,继续拉取...
3
收到拉取通知,继续拉取...
2

本文为了说明了ReentrantLock和Lock.newCondition()用法,其实上述的 “生产-消费”模型使用 阻塞队列 实现会简单很多。

2.重入读写锁,允许并发读,提高性能,下面是混合读写的锁控制模型:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantReadWriteLock;

class Account {
    int data = 0;
    final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    void processCachedData() throws Exception {
        rwl.readLock().lock();
        log("is reading ...");
        if (isOk()) {
            rwl.readLock().unlock();//写锁与读锁互斥,必需释放rwl的读锁后才能上rwl的写锁
            rwl.writeLock().lock();
            try {
                if (isOk()) {// 得到写锁后再判断,防止被其它线程抢先更改
                    log("is writing ...");
                    data += 3;// 进行写操作
                    //Thread.sleep(200000);//可以看到,加上写锁将不可再读
                    Thread.sleep(2);
                } else {
                    log("发现已被抢先更新,无需再更新。");
                }
            } finally {
                log("write over.");
                rwl.readLock().lock();// 在释放写锁之前最好先先获取读锁,以防止使用之前被其他写线程改变了数据状态
                rwl.writeLock().unlock(); // 释放写锁,但上面一句依旧保留了读锁,可防止写锁介入
            }
        }
        try {
            log("读取并使用数据:" + data--);
            Thread.sleep(1000);
        } finally {
            log("read over.");
            rwl.readLock().unlock();
        }
    }
    boolean isOk() {
        return data == 0;
    }
    void log(String msg) {
        System.out.println(Thread.currentThread().getName() + " " + msg);
    }
}
public class Test {
    public static void main(String[] args) {
        final Account account = new Account();
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            executorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        account.processCachedData();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        executorService.shutdown();
    }
}
输出:

pool-1-thread-1 is reading ...
pool-1-thread-1 is writing ...
pool-1-thread-1 write over.
pool-1-thread-1 读取并使用数据:3
pool-1-thread-2 is reading ...
pool-1-thread-2 读取并使用数据:2
pool-1-thread-3 is reading ...
pool-1-thread-3 读取并使用数据:1
pool-1-thread-4 is reading ...
pool-1-thread-5 is reading ...
pool-1-thread-1 read over.
pool-1-thread-2 read over.
pool-1-thread-3 read over.
pool-1-thread-4 is writing ...
pool-1-thread-4 write over.
pool-1-thread-4 读取并使用数据:3
pool-1-thread-4 read over.
pool-1-thread-5 发现已被抢先更新,无需再更新。
pool-1-thread-5 write over.
pool-1-thread-5 读取并使用数据:2
pool-1-thread-5 read over.
可以看出:

a.读写锁的优势在于允许同时加读锁以提供性能

b.读锁释放前不能加写锁

c.写锁释放前不能加读锁或写锁


3.一种更加常用的读写同步控制方式

import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * get 和 allKeys 是读操作
 * put 和 clear 是写操作
 * 读操作可以并发进行,但有写锁时会等写锁释放后再加读锁
 * 写操作不允许同时读或写,故必需先释放所有的读锁和写锁
 */
public class RWDictionary {
    private final Map<String, String> m = new TreeMap<String, String>();
    private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private final Lock r = rwl.readLock();
    private final Lock w = rwl.writeLock();
    public String get(String key) {
        r.lock();
        try {
            return m.get(key);
        } finally {
            r.unlock();
        }
    }
    public Object[] allKeys() {
        r.lock();
        try {
            return m.keySet().toArray();
        } finally {
            r.unlock();
        }
    }
    public String put(String key, String value) {
        w.lock();
        try {
            return m.put(key, value);
        } finally {
            w.unlock();
        }
    }
    public void clear() {
        w.lock();
        try { m.clear(); } finally { w.unlock(); }
    }
}
上面的例子中,有多个写操作和多个读操作,它们同样遵循原则:并发读、互斥写

上面的例子对非线程安全的集合进行了读写锁控制,比直接使用同步的集合(同步所有访问)效率更高!

1.30 Cubemx_STM32H743 SD_Card纳入文件管理系统 Cubemx_STM32H743 SD_Card纳入文件管理系统1、简介2、CubeMX配置 1、简介 和前面文章原理其实一样的。 1.29 Cubemx_STM32F429\H743 nandflash、spifalsh纳入文件管理系统 现在一并将SD卡、NandFlash、SPIFlash一并作为文件管理。 下面直接介绍SDcard,其他参考前面文章。 2、CubeMX配置 ... 阅读详情

相关推荐

Vitis HLS 学习指南与实践教程

Vitis HLS 学习指南与实践教程摘要:本文系统介绍了AMD Vitis HLS工具及其应用。HLS技术将C/C++代码自动转换为硬件描述语言,显著提升FPGA开发效率(5-10倍)。文章对比了HLS与传统RTL设计的优势,包括抽象级别高、开发周期短、代码重用性强等特点。详细讲解了Vitis HLS工具链的核心功能,包括支持的C/C++特性(如任意精度数据类型)、开发流程(项目创建-代码编写-仿真-综合)以及关键优化技术(流水线、循环展开、数组分割等编译指示)。通过具体代码示例展示了HLS设计方法,为F

weixin_44707118的博客 1401

ReentrantLock简介

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> ...

爱宝贝丶的博客 1422

Mac电脑用Latex论文排版3天速成5天实战de笔记

我后悔了,这五天竞赛搞得我视力都下降了...一个冲动的决定后成为数模竞赛论文写手,3天速成+5天时间=点亮攻克latex写论文技能💡关于Overleaf我是Mac,曾经按照大部分推荐的方式用TEXshop+vs code,但是把模板导入就开始报错。跟着少之又少的适配mac的教程(此时我已知道大概是走错路了)改了配置也无效。海鲜市场找佬改了半天,佬问我:一定要用VC吗?我说,那倒也不是。于是佬推荐我overleaf,三下五除二帮我挑配了环境,美汁汁收了我30块钱。

luwanjoyce的博客 2247

Java 独占锁ReentrantLock、读(悲观读)写锁ReentrantReadWriteLock、读(乐观读/悲观读)写锁StampedLock

锁必然要知道AbstractQueuedSynchronizer(AQS),AQS提供了一个框架,用于实现依赖于先进先出(FIFO)等待队列的阻塞锁和相关同步器(信号量、事件等)。独占,只有一个线程能执行,如ReentrantLock(悲观锁:除非线程1全部运行完后才会释放锁,否则其他线程无法拿到锁。可重入,公平与非公平特征 )Lock是juc中实现的锁接口,定义了锁的一些行为规范,他的设计目的是为了解决synchronized关键字在一些并发场景下不适用的问题,相对synchronized更灵活。....

CodingAnHour 753

高通camera:PDAF的配置与测试

确认相关log日志都已经打开了之后,判断是在3A算法中没有应用到PDAF,可能是之前在调试AF效果的时候关闭了PDAF,打开效果文件对应的文件夹,在\kamorta_lce_S5K3P9\Scenario.Default\XML\STATS。在log中搜索af_pdaf_proc_pd_single,这个函数是pdaf算法中的,源码被封装了,这里看不到,因此只能通过log打印出来的参数来分析pd是否正确,主要参数有pd ,defocus,confidence。PDAF的配置与测试。

arvin_xiong的博客 2486

ZYNQ平台上基于PHY芯片的IEEE1588/PTP高效实现方案

本文详细解析了在Xilinx ZYNQ平台上,如何通过选用支持IEEE1588/PTP的专用PHY芯片(如RTL8211FS-VS-CG、DP83640)来实现高精度时间同步的高效方案。文章对比了PS端与PL端MAC连接的优劣,提供了从硬件选型、接口设计、Linux驱动适配到PTP协议栈配置与性能优化的完整实战指南,并总结了关键避坑经验,为工业网络、电力系统等需要纳秒级同步的应用提供了清晰、可靠的实施路径。

kkk56的博客 1091

【JavaEE初阶】JUC(java.uitl.concurrent)的常见类

之前讲到Runnable接口,用于描述一个任务,通过Runnable中的run方法来体现的,但是描述的任务没有返回值(run方法是返回void),此处的Callable接口与Runnable接口类似,Callable里面的call方法是有返回值,表示这个线程执行结束要得到的结果是啥比如我们有以下需求创建线程计算 1 + 2 + 3 + …

2301_81510374的博客 777

OpenClaw 子代理配对失败问题分析与解决方案

OpenClaw子代理配对失败问题分析与解决方案 问题核心在于agent设备权限不足,仅有operator.approvals权限而缺少operator.admin权限,导致子代理启动时形成权限死锁。本文提供三种解决方案: 直接编辑设备配对文件(推荐):修改本地JSON文件,为agent设备添加完整operator.admin权限,操作简单快捷。 标准重新配对流程:删除现有agent设备后重新配对,通过正常审批流程获取完整权限,符合系统安全设计。 修改源码降低权限要求(仅限开发环境):调整子代理代码避免强制

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 149

工作之后,我对 ReentrantLock 有了新的理解

介绍 ReentrantLock 的核心源码以及常见问题。

qq_39552263的博客 1079

使用Python实现深度学习模型:智能极端天气事件预测

在本项目中,我们成功利用Python和Keras库构建了一个基于LSTM的极端天气预测模型。通过时间序列数据,模型能够识别天气趋势并预测未来的极端天气事件。尽管这是一个简化的示例,但它为实际应用中如何利用深度学习进行天气预测提供了一个很好的基础。随着更精确的数据和更多的特征信息,类似的模型可以进一步扩展到其他极端事件预测上,如风暴预警、气象灾害评估等。

Echo_Wish 730

磁环电感参数计算

电感饱和是指当电感中的电流超过一定阈值时,电感中的磁场无法继续增加,而是达到一个饱和状态,导致电感的感应电动势减小或消失。电感通常由线圈组成,当通过线圈的电流不断增加时,线圈内部的磁场也随之增加。然而,当电流达到一定程度时,线圈的铁芯磁化达到饱和,无法进一步增加磁场强度。电感饱和的阈值取决于电感的结构、材料和尺寸等因素。通常情况下,电感的额定电流会标明其饱和电流值。一旦电感中的电流超过了饱和电流,电感将饱和并出现异常行为。当我们谈论电感饱和的时候,实际上是在谈论磁芯饱和——空心的电感永远不会饱和。

小幽余生不加糖 4030

21 ReentrantLock(重入锁) & ReentrantReadWriteLock(读写锁)

 锁(重入锁,读写锁)它们具有比synchronized更为强大的功能,并且有嗅探锁定、多路分支等功能。重入锁,在需要进行同步的代码部分加上锁定,但不要忘记最后一定要释放锁定,不然会造成锁永远无法释放,其他线程永远进不去的结果。  package edu.sdut.lock; import java.util.concurrent.CopyOnWriteArrayList; imp...

Vision 833

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

什么是Lock?什么是ReentrantLock?ReentrantReadWriteLock又是啥?

ps:不要将获取锁的过程写在try块中,因为如果在获取锁(自定义锁的实现)时发生了异常,异常抛出的同时,也会导致锁无故释放。 目录 一.什么是Lock对象? 二.使用ReentrantLock实现线程同步 三.使用Lock对象实现线程间通信 四. 使用Lock对象和Condition实现等待/通知实例 五.使用Lock对象和多个Condition实现等待/通知实例 六、公平锁和非公平...

striveb的博客 1714

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Java多线程编程-(5)-使用Lock对象实现同步以及线程间通信

前几篇:Java多线程编程-(1)-线程安全和锁Synchronized概念Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性Java多线程编程-(3)-线程本地ThreadLocal的介绍与使用Java多线程编程-(4)-线程间通信机制的介绍与使用在《Java多线程编程-(4)-线程间通信机制的介绍与使用》已经学习了,可以使用方法wait/notify 结合同步关键字s

徐刘根的博客 8339

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java并发编程十 重入锁ReentrantLock 读写锁ReentrantReadWriteLock

Java并发编程十 重入锁ReentrantLock 读写锁ReentrantReadWriteLock Java的concurrent并发包提供了一套与Synchronized关键字相同功能Lock,还有与wait()/notify()相同功能的Condition。 Lock的功能比传统的Synchronized更加灵活。它具有嗅探锁定和多路分支等功能(一个lock对象可以创建多个Condi...

刘越洋子 357

并发编程中的锁

注意:解锁过程放入finally块中,加锁过程不要写在try里面;

2301_79567474的博客 634

Java高并发(六):ReentrantLock

目录LockReentrantLockReentrantReadWriteLockStampedLockReentrantLockReentrantLock实现原理AQS Lock Java中的Lock是J.U.C中的一个核心组件,J.U.C(java.util.concurrent)是在并发编程中常用的工具类,里面包含了很多在并发场景中使用的组件,比如线程池、阻塞队列、计时器、同步器、并发集合...

向日葵班学霸的博客 564

多线程锁的使用(ReentrantLock/Condition/ReentrantReadWriteLock)

锁在java多线程中,我们可以使用Synchronized关键字来实现线程间的同步互斥工作,那么其中有一个更优秀的机去完成这个”同步互斥”工作,它就是lock对象,我们主要学习两种锁重入锁和读写锁,他们具有比Synchronized更为强大的功能,并且有嗅探锁定、多路分支等功能。ReentrantLock重入锁在需要进行同步的代码部分加上锁定,但不要忘记最后一定要释放锁定,不然会造成锁永远无法释放,

zxiang248的专栏 426

Lock&Condition实现线程同步通信

Lock比传统线程模型中的synchronized方式更加面向对象, 与生活中的锁类似, 锁本身应该是一个对象. 两个线程执行的代码片段要实现同步互斥的效果, 谈么必须用一个Lock对象. 锁是在代表要操作的资源的类的内部方法中, 而不是线程代码中! ReentrantLock(重入锁) 在需要进行同步的代码部分加上锁,但不要忘记最后一定要释放锁,不然会造成锁永远无法释放,其它线程永远进

胖胖龙的博客 379

Java多线程专题笔记-下

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。提示:以下是本篇文章正文内容,下面案例可供参考Lock锁可以实现synchronized的效果,即实现原子性、有序性和可见性。但它属于轻量级锁,可以手动获取锁和释放锁、可中断的获取锁、超时获取锁。Lock只能给代码块上锁,synchronized可以给方法和代码块上锁。

书生的博客 313

【Java从入门到入土】37:Lock锁:synchronized的升级版

文章摘要: Java并发编程中,Lock锁是比synchronized更强大的线程同步机制。ReentrantLock作为Lock接口的核心实现,提供了显式锁操作、可重入性、可中断和超时获取等高级特性。文章详细对比了synchronized和ReentrantLock的用法差异,展示了ReentrantLock在可中断锁、超时锁方面的优势。同时深入分析了公平锁与非公平锁的区别,公平锁保证线程按顺序获取但性能较低,非公平锁允许插队但吞吐量更高。通过代码示例演示了不同锁模式在并发场景下的实际应用,为开发者提供了

老前端的功夫 652

【Java并发】-- Lock体系

在 Lock 接口出现之前, Java 中的应用程序对于多线程的并发安全处理只能基于synchronized 关键字来解决。但是 synchronized 在有些场景中会存在一些短板,也就是它并不适合于所有的并发场景。 但是在 Java5 以后, Lock 的出现可以解决synchronized 在某些场景中的短板,它比 synchronized 更加灵活。 Lock 的实现 Lock 本质上是...

十年磨一剑,沉淀…… 573

Java多线程编程--使用Lock对象实现同步以及线程间通信

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.youkuaiyun.com/u010870518/article/details/78197583 前几篇: Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编...

liyang_com的博客 186

显示锁AQS

1、synchronized属于隐式锁,即锁的持有与释放都是隐式的,我们无需干预 2、显式锁,即锁的持有和释放都必须由我们手动编写 3、重入锁ReetrantLock,所谓锁的公平和非公平 如果在时间上,先对锁进行获取的请求,一定先被满足,这个锁就是公平的,不满足,就是非公平的 非公平的效率一般来讲更高 4、ReadWriteLock接口和读写锁ReentrantReadWriteLock 读写锁...

qq_43801646的博客 137
上一篇: java 多线程同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Exchanger)
下一篇: java 枚举
conquer0715
博客等级 码龄18年 73粉丝 147原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值