AQS的应用:可重入锁和读写锁

3. Matérn协方差模型与随机偏微分方程 对应的高斯马尔可夫随机场 (GMRF)可以通过使用某种随机偏微分方程(SPDE)明确构造,当由高斯白噪声驱动时,随机偏微分方程的解是具有 Matérn 协方差函数的高斯场(GF) 阅读详情

一、Lock接口

1、Lock

​ Lock跟Synchronized一样,都是用在多线程中用来控制并发,保证共享资源安全的一种同步机制。

Synchronized是隐式的加锁/解锁;而Lock是显示的加锁/解锁,也就是说我们使用的时候需要先lock.lock()锁定资源,执行逻辑,用完后在lock.unlock()释放资源。

2、特性

​ Lock有Synchronized没有的特性,这几个特性使我们在开发中更方便灵活

​ 1、非阻塞性获取同步状态。tryLock方法可以立即返回是否获取到同步状态,先尝试获取一次,有就有,没有就没有,不用去等待;

​ 2、支持中断。自己释放不了同步状态,可以被中断,通过中断信号跳出某种状态,拿到同步状态干到一半干不下去就不干了释放同步状态给别人用吧。lockInterruptbly()是响应中断方法。

​ 3、支持超时。到一定时间再干不完就不干了,释放同步状态。支持带时间参数的tryLock()。

3、用法

lock.lock()加锁;lock.unlock()解锁。

/**
 * Lock的标准用法,注意两点:
 * 1、try外上锁
 * 2、finlly里解锁
 */
public class LockUseCase {
    static Lock lock = new ReentrantLock();//定义锁
    public static void main(String[] args) {
        lock.lock();//try外上锁
        try{
            //todo 业务逻辑
        }finally {
            lock.unlock();//解锁
        }
    }
}

为什么要将lock放到try外面呢?因为lock方法可能会抛出异常,在try内使用,加锁的时候如果抛出异常加锁失败就进入finally里去解锁,加锁都没成功,解锁自然也会抛出异常;而在try外使用,如果加锁抛出异常就不走finally了,没有加锁自然也不会解锁,当然没问题。lock()是自定义同步方法,跟进源码会发现不管是公平模式还是非公平模式都有一大串的代码,要尝试获取同步状态,获取不成功还要入队,等待,被唤醒等操作,这过程也存在抛异常的可能,lock方法不去捕获异常,遇到问题就直接中断了,不会影响其他线程,这样更安全。总之,在try外使用就是防止lock抛异常时出现问题。

二、可重入锁 ReentrantLock

1、ReentrantLock

​ 由名字可以看出,他跟synchronized一样,同一个线程可以多次拿锁,并且它有两种模式获取锁:公平模式获取同步状态和非公平模式获取同步状态。公平模式就是按入队顺序,挨个出队去拿同步状态,非公平模式是争抢式拿同步状态,谁抢到就是谁的。效率上肯定是非公平模式更高,默认就是非公平模式。

2、源码

/***
 * 可重入锁。独占式锁的代表,AQS的一个应用
 * 它支持公平和非公平获取同步状态
 */
public class ReentrantLock implements Lock, java.io.Serializable {
    private final Sync sync;
    //自定义同步器,继承AQS。这是一个大方面的抽象类同步器,下面再细分公平和非公平同步器
    abstract static class Sync extends AbstractQueuedSynchronizer {
        abstract void lock();//定义抽象方法,子类去具体实现
        /***
         * 定义一个非公平获取同步状态的方法,由子类非公平同步器调用
         * 公平获取同步状态的方法在AQS里已经存在了,子类直接重写就可以了
         * 非阻塞式,立即返回结果;是否获取成功
         */
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {//同步状态没有被占用,是空闲的,尝试用cas获取同步状态
                if (compareAndSetState(0, acquires)) {//cas获取成功
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            //如果当前线程就是获取了同步状态的线程,说明这是重新进入(可重入锁实现逻辑),可以获取同步状态
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
        
        //重写方法:独占式释放同步状态
        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }
        //持有同步状态的线程是否是当前线程
        protected final boolean isHeldExclusively() {
            return getExclusiveOwnerThread() == Thread.currentThread();
        }
    }

    //自定义的非公平模式同步器
    static final class NonfairSync extends Sync {
        //自定义方法:阻塞式获取同步状态,既然式获取同步状态了,肯定式同步资源没被占用,所以是0
        final void lock() {
            //下面就是争抢了,谁先cas成功,就把同步资源给那个线程,cas不成功的只能进入等待队列了
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
            }else {
                acquire(1);//调用模板方法:aqs的独占式获取同步状态,模板方法会调用下面重写的那个方法
            }
        }
        //重写方法:独占式获取同步状态
        protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }
    }
    
    //自定义的公平模式同步器
    static final class FairSync extends Sync {
        //自定义方法:阻塞式获取同步状态,公平模式原理就是从等待队列里挨个取,先进先出原则
        final void lock() {
            acquire(1);//调用模板方法:aqs的独占式获取同步状态,模板方法会调用下面重写的那个方法
        }
        //重写方法:独占式获取同步状态
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) {//没有前驱节点并且能够获取同步资源
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                setState(nextc);
                return true;
            }
            return false;
        }
    }
    //两个构造函数,默认是非公平模式
    public ReentrantLock() {
        sync = new NonfairSync();
    }
    //参数可以指定用哪种模式
    public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
    public void lock() {
        sync.lock();
    }
    public void lockInterruptibly() throws InterruptedException {
        sync.acquireInterruptibly(1);
    }
    public boolean tryLock() {
        return sync.nonfairTryAcquire(1);
    }
    public void unlock() {
        sync.release(1);
    }
}

三、读写锁 ReentrantReadWriteLock

1、读写锁

​ 现实中大部分场景都是读多写少的,读写锁正是这种背景下诞生。读写锁分为读锁和写锁,读锁是共享式获取同步状态,同一时刻可以有多个线程获的同步状态;写锁是独占式获取同步状态,是排他锁,同一时刻只能有一个线程获取同步状态。

​ 如果写线程正在执行写操作,其他线程都会被阻塞,禁止获取读或写操作,原因要是保证变量的可见性。也就是说只要有线程拿着读锁,写锁一定被获取不到。

​ 一个同步状态的变量要维护两个状态(读写)是通过对int类型变量切分实现的,同步状态是一个int类型变量,是占32位,把他分成高16位代表读,低16位代表写。这样读写状态的改变通过int类上高低16位的位运算计算就可以实现了。

2、锁降级

​ 锁降级是指由写锁降级为读锁的过程。写是排他性的,只能有一个进行,所以级别比较高;读是共享的,可以多个同时进行,级别低。

​ 锁降级的过程是先拿到写锁,再去拿读锁,再释放写锁。

​ 为啥会有这个过程,不是直接释放写锁去拿读锁?如果直接释放写锁,可能刚释放会被其他线程拿到写锁,其他线程修改了你的值,你再去用就不是你想要的值了,如果在持有写锁的过程中再拿读锁,这样即使释放了写锁,其他线程也无法拿到写锁,因为你本身在占据着读锁,这保证了数据变量的可见性。

3、用法

public class LockUseCase {
    static ReadWriteLock rwLock = new ReentrantReadWriteLock();
    static Lock readLock = rwLock.readLock();
    static Lock writeLock = rwLock.writeLock();
    public static void readTest(){
        readLock.lock();
        try{
            //todo 业务逻辑
        }finally {
            readLock.unlock();
        }
    }
    public static void writeTest(){
        writeLock.lock();
        try{
            //todo 业务逻辑
        }finally {
            writeLock.unlock();
        }
    }
}

4、部分源码

/**
 * 可重入读写锁。支持读锁(共享式获取同步状态)和写锁(独占式获取同步状态),也是AQS的应用
 */
public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable {
    private final  ReadLock readerLock;
    private final  WriteLock writerLock;
    final Sync sync;
    public ReentrantReadWriteLock() {
        this(false);
    }
    /***
     * 构造函数就确定了是否是公平模式并且创建了读锁实例和写锁实例
     * @param fair
     */
    public ReentrantReadWriteLock(boolean fair) {
        sync = fair ? new  FairSync() : new  NonfairSync();
        readerLock = new  ReadLock(this);
        writerLock = new  WriteLock(this);
    }
    public  WriteLock writeLock() { return writerLock; }
    public  ReadLock  readLock()  { return readerLock; }
    /**
     * 内部类形式的自定义同步器
     * 一个state状态怎么区分读写的呢?通过高低16位,位运算来实现.
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        static final int SHARED_SHIFT   = 16;
        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
        static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }//共享式同步资源数量
        static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }//独占式同步资源数量
        static final class HoldCounter {
            int count = 0;
            final long tid = getThreadId(Thread.currentThread());
        }
        static final class ThreadLocalHoldCounter extends ThreadLocal< Sync.HoldCounter> {
            public  Sync.HoldCounter initialValue() {
                return new  Sync.HoldCounter();
            }
        }
        //重写方法:释放独占式同步资源
        protected final boolean tryRelease(int releases) {
            int nextc = getState() - releases;
            boolean free = exclusiveCount(nextc) == 0;
            if (free)
                setExclusiveOwnerThread(null);
            setState(nextc);
            return free;
        }

        /***
         * 重写写锁(独占式)获取同步状态方法
         * @param acquires
         * @return
         */
        protected final boolean tryAcquire(int acquires) {
            Thread current = Thread.currentThread();
            int c = getState();//获取同步状态
            int w = exclusiveCount(c);//获取独占(写锁)它的数量
            if (c != 0) {//同步状态已经被拿到了,有可能是它或者其他线程
                //当前线程不是已经获取写锁的线程,返回获取失败
                if(current != getExclusiveOwnerThread()){
                    return false;
                }
                //已经获取了同步状态,但是写锁呢又是0,所以这个同步状态是读锁的
                //存在读锁,也返回失败
                if (w == 0) {
                    return false;
                }
                //给同步状态加1计数,是当前线程重入的
                setState(c + acquires);
                return true;
            }
            //还没线程占有同步状态
            //如果写锁被阻塞了,已经被别人拿了写锁就返回失败
            if(writerShouldBlock()){
                return false;
            }
            //如果cas设置同步状态失败,返回失败
            if (!compareAndSetState(c, c + acquires)){
                return false;
            }
            //否则,设置上当前线程后返回成功
            setExclusiveOwnerThread(current);
            return true;
        }
        /***
         * 重写 读锁(共享锁)获取同步状态方法
         * @param unused
         * @return
         */
        protected final int tryAcquireShared(int unused) {
            Thread current = Thread.currentThread();
            int c = getState();//一个同步状态通过“按位切割”高低16位运算记录读状态和写状态
            //独占锁(写锁)已经被获取了,并且还不是本线程
            if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) {
                return -1;
            }
            int r = sharedCount(c);//获取共享(读锁)得同步状态数量
            if (!readerShouldBlock() && r < MAX_COUNT &&  compareAndSetState(c, c + SHARED_UNIT)) {
                if (r == 0) {//如果读之前没被获取过
                    firstReader = current;
                    firstReaderHoldCount = 1;
                } else if (firstReader == current) {
                    firstReaderHoldCount++;
                } else {
                     Sync.HoldCounter rh = cachedHoldCounter;
                    if (rh == null || rh.tid != getThreadId(current))
                        cachedHoldCounter = rh = readHolds.get();
                    else if (rh.count == 0)
                        readHolds.set(rh);
                    rh.count++;
                }
                return 1;
            }
            return fullTryAcquireShared(current);
        }
}
关于React Native Android找不到node的错误 最近,按照官方文档初始化了一个React Native项目,但是在Android端运行的时候,报了如下的一个错误。 org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:recordFilesBeforeBundleCommandDebug'. Caused by: org.gradle.process.internal.ExecException: A problem occurred starting p 阅读详情

相关推荐

利用Langchain生成合成数据的实践指南

合成数据是相对于从真实世界事件中收集的数据而言的人工生成的数据。它用于模拟真实数据,同时避免隐私泄露或遇到真实数据中的局限性。:尽管合成数据有诸多优点,但应谨慎使用,因为它可能无法捕捉真实世界的复杂性。

eahba的博客 398

一篇文章彻底搞懂AQS之ReentrantReadWriteLock(读写锁,深度剖析)

围绕ReentrantReadWriteLock(读写锁),如何使用、使用场景、核心源码分析。

大尾巴狼学编程的博客 1080

软件项目成本控制实战:从COCOMO模型到挣值分析的5个关键步骤

本文详细介绍了软件项目成本控制的5个关键步骤,从COCOMO模型估算到挣值分析预警,帮助中小型团队精准管理预算。通过简化COCOMO II的有机模式、动态建立成本基准、轻量化挣值分析等方法,项目经理可以有效应对预算超支和进度延误问题,提升项目成功率。

weixin_30733003的博客 227

Java多线程篇(9)——AQS之读写锁(ReentrantReadWriteLock)

Java多线程篇(9)——AQS之读写锁(ReentrantReadWriteLock)

笔记罢了 826

word 2013 长篇文档排版案例教程

office 2013 制作长文格式模板

1万+

【老生谈算法】可视化通道流中瞬时涡量场的算法实现与MATLAB源码分析——瞬时涡量场

本文旨在探讨可视化通道流中瞬时涡量场的方法,并通过MATLAB编程实现这一过程。涡量场作为描述流体旋涡强度和方向的重要物理量,对于理解复杂流体运动具有重要意义。本文首先介绍了涡量场的基本概念,随后详细阐述了从测量数据收集到涡量场可视化的完整流程,并给出了相应的MATLAB源码。通过实际运行该源码,我们展示了涡量场的可视化结果,并讨论了其在流动结构识别和动力学行为理解中的应用。关键词: 涡量场;流体运动;MATLAB;可视化;PIV一、引言。

m0_53407570的博客 1125

1.3.2 AQS 读写锁

1.读写锁原理 2.利用读写锁写一个安全的HashMap 读写锁原理 ReadWriteLock:维护一对关联锁,一个读锁一个写锁,读锁可以由多个线程同时获得,写锁只能被一个线程获得。同一时间,读锁和写锁不能被不同线程同时获得。 1.th1想获取写锁,检查readCount==0,满足,说明读锁未被占用,此时可抢写锁;检查writeCount==0说明写锁未被占用,采用CAS修改...

weixin_30293135的博客 365

国产数据库迁移必看:达梦到ES的CDC方案优化全记录(含完整代码)

本文详细记录了从达梦数据库到Elasticsearch的CDC方案优化全过程,涵盖触发器方案局限性、Debezium架构优势及完整代码实现。通过Flink集成和性能调优,实现毫秒级延迟同步,显著降低数据库负载,为国产数据库迁移提供可落地的技术方案。

weixin_29079671的博客 499

并发编程(六):AQS之读写锁ReentrantReadWriteLock

一,AQS源码博文:并发编程:AbstractQueuedSynchronizer源码分析 二,ReentrantReadWriteLock读写锁介绍 1,读写锁介绍 ReentrantReadWriteLock 虽然与 ReentrantLock 没有直接关系,但是在功能上算是对 ReentrantLock 的扩展。在 ReentrantLock 重入独占锁的功能上,添加了共享锁...

zp_zhang的博客 374

多物理场光学仿真软件:COMSOL_(10).激光器与谐振腔仿真

定义Nd:YAG晶体的材料属性% 折射率% 吸收系数% 发射截面% 定义光泵浦源% 泵浦光波长% 泵浦光强度% 泵浦光方向% 定义全反射镜% 选择边界% 完美电导体边界条件% 定义部分反射镜% 选择边界% 反射率边界条件% 反射率通过 COMSOL 对激光器和光学谐振腔进行仿真,可以全面评估激光器的性能,包括输出功率、效率、稳定性和模式选择等。这些仿真结果为激光器的设计和优化提供了重要的参考依据。

kkchenjj的博客 1649

[网络安全提高篇] 一二〇.恶意软件动态分析经典沙箱Cape批量提取动态API特征

这是作者网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您喜欢,一起进步。前文详细介绍动态分析沙箱Cape的安装过程,其是一个开源的自动恶意软件分析系统,通过自动运行和分析恶意软件,全面分析和提取恶意软件的关键特征。然而,当样本数量增加时,单个样本分析会降低效率。这篇文章将讲解如何实现Cape沙箱的批量分析,通过调用Python脚本文件来实施批量处理,并将分析结果存储在指定位置,最后补充submit.py的参数及Python调用方式。基础性文章,希望对您有帮助!

杨秀璋的专栏 4122

基于 AQS 实现读写锁

AQS -- AbstractQueuedSynchronizer 首先介绍一下 AbstractQueuedSynchronizer (抽象队列同步器): 队列同步器AbstractQueuedSynchronizer(以下简称同步器),是用来构建锁或者其他同步组件的基础框架;位于 java.util.concurrent.locks 包下; 它使用了一个信号量(state)表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作; AbstractQueuedSynchronizer 使

kiss_kings的博客 1497

如何让C++程序生成dump文件?生成dump文件的方式有哪些?如何使用Windbg分析dump文件?

本文详细介绍了如何让C++程序生成dump文件、生成dump文件的多种方式以及如何使用Windbg分析dump文件,并给出了对应的实战分析案例,有一定的实战参考价值。

dvlinker的技术专栏 5万+

实际场景解读AQS读写锁ReentrantReadWriteLock

前面讲了什么是AQS.并且基于Reentrantlock已经看了一部分AQS方法. AQS是什么?基于ReentrantLock解密! 但是其实真实项目中一般使用ReetrantLock,一般都是synchronized. 因为在jdk1.6之后,synchronized底层实现里面,里面做了一些计数器的维护,加锁释放锁,CAS啊.都能实现ReentrantLock一样的效果.而且使用起来相对简单. 另外读写锁ReentrantReadWriteLock其实也挺常用的 下面就接着看对于Reentra..

qq_25933841的博客 1908

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

深度学习工具包 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")

十、详解ReentrantReadWriteLock读写锁

之前我们讲过可重入锁从这篇博文中我们可以了解到,基于lock的锁底层都是利用aqs这个抽象类的。那么在读写锁中,其本质也是利用aqs,与可重入锁之间的区别的就是在实现抽象方法的时候,具体的逻辑不一样。可以理解为两者骨架一样,但是具体细节逻辑有区别,尤其是在tryAcquire和tryRelease的逻辑不一样。

2301_77203215的博客 1088

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

可重入的读写锁-ReentrantReadWriteLock及AQS源码分析

1 读写锁维护了一对相关的锁,一个用于只读操作,一个用于写入操作。 只要没有writer,读锁可以由多个reader线程同时保持。 写锁是独占的。 互斥锁一次只允许一个线程访问共享数据,哪怕进行的是只读操作 读写锁允许对共享数据进行更高级别的并发访问 对于写操作,一次只有一个线程(write线程)可以修改共享数据 对于读操作,允许任意数量的线程同时进行读取。 与互斥锁相比,使用读写锁能否...

JavaEdge全是干货的技术号 2317

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java多线程 同步队列详解(AQS)

Java多线程 同步队列详解(AQS) 文章目录Java多线程 同步队列详解(AQS)1、AQS简介1.1 什么是AQS1.2 什么是CLH锁队列2、ASQ 提供的各种锁实现流程2.1 独占锁2.2 共享锁2.3 可重入锁2.4 公平锁与非公平锁2.5 读写锁 1、AQS简介 1.1 什么是AQS 队列同步器(AQS)是用来构建锁或者其他同步组件的基础框架,使用一个int型变量代表同步状态,通过内...

烟雨gps 1869

AQS 混合模式 之可重入的读写锁ReentrantReadWriteLock

AQS 实现ReenTrantReadWriteLock 学习

nobaldnolove的博客 321

从 synchronized 到 CAS 和 AQS的超详细解析

CAS AQS synchronized

Qgchun. 1461

java可重入读_我之见--java多线程之可重入锁,读写锁源码分析 及自定义锁AQS

ReentrantLock锁是jdk1.5之后加的轻量级锁,相对以前的重量级锁,它有很多的优势。ReentrantLock只支持独占方式的获取操作,它将同步状态用于保存锁获取操作的次数,并且还维护一个owner变量来保存当前所有的线程标识符,只有当线程获取或者释放锁的时候才会修改这个变量。1. 可重入锁的源码分析:当我打开的ReentrantLock源码的时候发现它的代码却是非常简单的。总共有三个...

weixin_39548740的博客 181

深入分析实战可重入读写锁ReentrantReadWriteLock

在读多写少的情况下可重入锁ReentrantLock可能不是那么完美,比如缓存的写入和读取。今天,我们就引出可重入读写锁ReentrantReadWriteLock,其读写分离的机制,大大提升缓存场景的系统性能。

勤于笔记,成于点滴。 1229

Java线程学习入门(三):公平锁、可重入锁、死锁、AQS组件、读写锁

公平锁、可重入锁、死锁、AQS组件、读写锁

qq_43568982的博客 356

AQS和CAS的简单理解和部分锁理解

AQS和CAS的简单理解和部分锁理解

zhk 1466

AQS的应用

AQS的应用

qq_51240148的博客 507

java中的锁详解

AQS就是AbstractQueuedSynchronizer抽象类,AQS其实就是JUC包下的一个基类,JUC下的很多内容都是基于AQS实现了部分功能,比如ReentrantLock,ThreadPoolExecutor,阻塞队列,CountDownLatch,Semaphore,CyclicBarrier等等都是基于AQS实现。首先AQS中提供了一个由volatile修饰,并且采用CAS方式修改的int类型的state变量。

埃泽漫笔 2873

Java中锁的分类,公平锁、乐观锁、悲观锁、可重入锁

AQS就是AbstractQueueSynchronizer抽象类,是JUC包下的一个基类,JUC下的很多内容都是基于AQS实现了部分功能,比如ReentrantLock,ThreadPoolExecutor,阻塞队列,CountDownLatch,Semaphore,CyclicBarrier等等都是基于AQS实现。AQS提供了一个由volatile修饰,并且采用CAS方式修改的int类型的state变量;其次AQS维护了一个双向链表,有head,有tail,并且每个节点都是Node对象。

qq_54472227的博客 947
上一篇: AQS 队列同步器
下一篇: Nginx + upstream prematurely closed connection while reading response header from upstream
csdn_binger
博客等级 码龄11年 2粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值