精华内容
下载资源
问答
  • 可重入不可重入锁 public class ReenterLockDemo { public static void main(String[] args) { Phone phone = new Phone(); ExecutorService executorService = Executors.newFixedThreadPool(2); // for(int i =...

    可重入不可重入锁

    /**
     * @ClassName ReenterLockDemo
     * @Description 可重入锁(也叫递归锁)
     *
     * 指的是同一线程 外层函数获得锁之后,内层递归函数仍然能获得该锁的代码
     * 在同一个线程的外层方法获取锁的时候,进入内层方法时会自动获得该锁
     *
     * 也就是说 线程可以进入任何一个他已经拥有的锁所同步着的代码块
     **/
    public class ReenterLockDemo {
        public static void main(String[] args) {
            Phone phone = new Phone();
            ExecutorService executorService = Executors.newFixedThreadPool(2);
    //        for(int i =0; i < 100; i++){
    //            executorService.execute(()-> {
    //                try {
    //                    phone.sendMsg();
    //                } catch (Exception e) {
    //                    e.printStackTrace();
    //                }
    //            });
    //        }
            for(int i =0; i < 2; i++){
                executorService.execute(phone);
            }
            executorService.shutdown();
        }
    }
    class Phone implements Runnable{
        public synchronized void sendMsg() throws Exception{
            System.out.println(Thread.currentThread().getName() + "sendMsg");
            sendEmail();
        }
        public synchronized void sendEmail() throws Exception{
            System.out.println(Thread.currentThread().getName() + "sendEmail");
        }
        Lock lock = new ReentrantLock();
        @Override
        public void run() {
            get();
        }
        public void get(){
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + "get");
                set();
            }finally {
                lock.unlock();
            }
        }
        public void set(){
            lock.lock();
            System.out.println(Thread.currentThread().getName() + "set");
            lock.unlock();
        }
    }
    

    自旋锁

    
    /**
     * @ClassName SpinLockDemo
     * @Description 自旋锁
     *
     * 自旋锁是指尝试获取锁的线程不会立即堵塞,而是采用循环的方式尝试去获取锁
     * 这样的好处是可以减少线程上下文的切换, 缺点是循环会消耗cpu
     **/
    public class SpinLockDemo {
        AtomicReference<Thread> atomicReference = new AtomicReference<>();
    
        public void myLock(){
            Thread thread = Thread.currentThread();
            System.out.println(thread.getName() + "\t come in !");
            while (!atomicReference.compareAndSet(null,thread)){
            //    System.out.println("我转!我转!");
            }
        }
        public void myUnLock(){
            Thread thread = Thread.currentThread();
            atomicReference.compareAndSet(thread,null);
            System.out.println(thread.getName() + "\t myUnLock !");
        }
        public static void main(String[] args) throws InterruptedException {
            SpinLockDemo demo = new SpinLockDemo();
            new Thread(() ->{
                demo.myLock();
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                demo.myUnLock();
            },"AA").start();
    
            TimeUnit.SECONDS.sleep(1);
    
            new Thread(() ->{
                demo.myLock();
                demo.myUnLock();
            },"BB").start();
        }
    }
    

    独占锁(写锁),共享锁(读锁),互斥锁

    /**
     * @ClassName ReadWriteLockDemo
     * @Description 互斥锁
     *
     * 多个线程同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源时,应该可以同时进行
     * 但是如果有一个线程尝试去写共享资源时,就不应该有其他的线程去读或者写
     * 小总结: 读-读 能共存
     *          读-写 不能共存
     *          写-写 不能共存
     **/
    class MyCache{
        private volatile Map<String, Object> map = new HashMap<>();
        private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    
        public void put(String key, Object value) {
            rwLock.writeLock().lock();
            try {
                System.out.println(Thread.currentThread().getName() + "\t 正在写入: " + key);
                try {
                    TimeUnit.MILLISECONDS.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                map.put(key, value);
                System.out.println(Thread.currentThread().getName() + "\t 写入完成 ");
            }catch (Exception e){
            }finally {
                rwLock.writeLock().unlock();
            }
    
        }
        public void get(String key) {
            rwLock.readLock().lock();
                try {
                System.out.println(Thread.currentThread().getName() + "\t 正在读取");
                try {
                    TimeUnit.MILLISECONDS.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "\t 读取完成: " + map.get(key));
            }catch (Exception e){
            }finally {
                rwLock.readLock().unlock();
            }
        }
    }
    public class ReadWriteLockDemo {
    
        public static void main(String[] args) {
            MyCache myCache = new MyCache();
    
            for(int i = 1; i <= 5; i++){
                final int ii = i;
                new Thread(()-> myCache.put(ii + "", ii + "")
                ,String.valueOf(i)).start();
            }
    
            for(int i = 1; i <= 5; i++){
                final int ii = i;
                new Thread(()-> myCache.get(ii + "")
                        ,String.valueOf(i)).start();
            }
        }
    }
    
    
    展开全文
  • 可重入不可重入锁/*** @ClassName ReenterLockDemo* @Description 可重入锁(也叫递归锁)** 指的是同一线程 外层函数获得锁之后,内层递归函数仍然能获得该锁的代码* 在同一个线程的外层方法获取锁的时候,进入内层...

    可重入不可重入锁

    /**

    * @ClassName ReenterLockDemo

    * @Description 可重入锁(也叫递归锁)

    *

    * 指的是同一线程 外层函数获得锁之后,内层递归函数仍然能获得该锁的代码

    * 在同一个线程的外层方法获取锁的时候,进入内层方法时会自动获得该锁

    *

    * 也就是说 线程可以进入任何一个他已经拥有的锁所同步着的代码块

    **/

    public class ReenterLockDemo {

    public static void main(String[] args) {

    Phone phone = new Phone();

    ExecutorService executorService = Executors.newFixedThreadPool(2);

    // for(int i =0; i < 100; i++){

    // executorService.execute(()-> {

    // try {

    // phone.sendMsg();

    // } catch (Exception e) {

    // e.printStackTrace();

    // }

    // });

    // }

    for(int i =0; i < 2; i++){

    executorService.execute(phone);

    }

    executorService.shutdown();

    }

    }

    class Phone implements Runnable{

    public synchronized void sendMsg() throws Exception{

    System.out.println(Thread.currentThread().getName() + "sendMsg");

    sendEmail();

    }

    public synchronized void sendEmail() throws Exception{

    System.out.println(Thread.currentThread().getName() + "sendEmail");

    }

    Lock lock = new ReentrantLock();

    @Override

    public void run() {

    get();

    }

    public void get(){

    lock.lock();

    try {

    System.out.println(Thread.currentThread().getName() + "get");

    set();

    }finally {

    lock.unlock();

    }

    }

    public void set(){

    lock.lock();

    System.out.println(Thread.currentThread().getName() + "set");

    lock.unlock();

    }

    }

    自旋锁

    /**

    * @ClassName SpinLockDemo

    * @Description 自旋锁

    *

    * 自旋锁是指尝试获取锁的线程不会立即堵塞,而是采用循环的方式尝试去获取锁

    * 这样的好处是可以减少线程上下文的切换, 缺点是循环会消耗cpu

    **/

    public class SpinLockDemo {

    AtomicReference atomicReference = new AtomicReference<>();

    public void myLock(){

    Thread thread = Thread.currentThread();

    System.out.println(thread.getName() + "\t come in !");

    while (!atomicReference.compareAndSet(null,thread)){

    // System.out.println("我转!我转!");

    }

    }

    public void myUnLock(){

    Thread thread = Thread.currentThread();

    atomicReference.compareAndSet(thread,null);

    System.out.println(thread.getName() + "\t myUnLock !");

    }

    public static void main(String[] args) throws InterruptedException {

    SpinLockDemo demo = new SpinLockDemo();

    new Thread(() ->{

    demo.myLock();

    try {

    TimeUnit.SECONDS.sleep(5);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    demo.myUnLock();

    },"AA").start();

    TimeUnit.SECONDS.sleep(1);

    new Thread(() ->{

    demo.myLock();

    demo.myUnLock();

    },"BB").start();

    }

    }

    独占锁(写锁),共享锁(读锁),互斥锁

    /**

    * @ClassName ReadWriteLockDemo

    * @Description 互斥锁

    *

    * 多个线程同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源时,应该可以同时进行

    * 但是如果有一个线程尝试去写共享资源时,就不应该有其他的线程去读或者写

    * 小总结: 读-读 能共存

    * 读-写 不能共存

    * 写-写 不能共存

    **/

    class MyCache{

    private volatile Map map = new HashMap<>();

    private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

    public void put(String key, Object value) {

    rwLock.writeLock().lock();

    try {

    System.out.println(Thread.currentThread().getName() + "\t 正在写入: " + key);

    try {

    TimeUnit.MILLISECONDS.sleep(300);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    map.put(key, value);

    System.out.println(Thread.currentThread().getName() + "\t 写入完成 ");

    }catch (Exception e){

    }finally {

    rwLock.writeLock().unlock();

    }

    }

    public void get(String key) {

    rwLock.readLock().lock();

    try {

    System.out.println(Thread.currentThread().getName() + "\t 正在读取");

    try {

    TimeUnit.MILLISECONDS.sleep(300);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println(Thread.currentThread().getName() + "\t 读取完成: " + map.get(key));

    }catch (Exception e){

    }finally {

    rwLock.readLock().unlock();

    }

    }

    }

    public class ReadWriteLockDemo {

    public static void main(String[] args) {

    MyCache myCache = new MyCache();

    for(int i = 1; i <= 5; i++){

    final int ii = i;

    new Thread(()-> myCache.put(ii + "", ii + "")

    ,String.valueOf(i)).start();

    }

    for(int i = 1; i <= 5; i++){

    final int ii = i;

    new Thread(()-> myCache.get(ii + "")

    ,String.valueOf(i)).start();

    }

    }

    }

    本文地址:https://blog.csdn.net/qq_38854914/article/details/107379037

    希望与广大网友互动??

    点此进行留言吧!

    展开全文
  • 可重入不可重入锁/*** @ClassName ReenterLockDemo* @Description 可重入锁(也叫递归锁)** 指的是同一线程 外层函数获得锁之后,内层递归函数仍然能获得该锁的代码* 在同一个线程的外层方法获取锁的时候,进入内层...

    可重入不可重入锁

    /**

    * @ClassName ReenterLockDemo

    * @Description 可重入锁(也叫递归锁)

    *

    * 指的是同一线程 外层函数获得锁之后,内层递归函数仍然能获得该锁的代码

    * 在同一个线程的外层方法获取锁的时候,进入内层方法时会自动获得该锁

    *

    * 也就是说 线程可以进入任何一个他已经拥有的锁所同步着的代码块

    **/

    public class ReenterLockDemo {

    public static void main(String[] args) {

    Phone phone = new Phone();

    ExecutorService executorService = Executors.newFixedThreadPool(2);

    // for(int i =0; i < 100; i++){

    // executorService.execute(()-> {

    // try {

    // phone.sendMsg();

    // } catch (Exception e) {

    // e.printStackTrace();

    // }

    // });

    // }

    for(int i =0; i < 2; i++){

    executorService.execute(phone);

    }

    executorService.shutdown();

    }

    }

    class Phone implements Runnable{

    public synchronized void sendMsg() throws Exception{

    System.out.println(Thread.currentThread().getName() + "sendMsg");

    sendEmail();

    }

    public synchronized void sendEmail() throws Exception{

    System.out.println(Thread.currentThread().getName() + "sendEmail");

    }

    Lock lock = new ReentrantLock();

    @Override

    public void run() {

    get();

    }

    public void get(){

    lock.lock();

    try {

    System.out.println(Thread.currentThread().getName() + "get");

    set();

    }finally {

    lock.unlock();

    }

    }

    public void set(){

    lock.lock();

    System.out.println(Thread.currentThread().getName() + "set");

    lock.unlock();

    }

    }

    自旋锁

    /**

    * @ClassName SpinLockDemo

    * @Description 自旋锁

    *

    * 自旋锁是指尝试获取锁的线程不会立即堵塞,而是采用循环的方式尝试去获取锁

    * 这样的好处是可以减少线程上下文的切换, 缺点是循环会消耗cpu

    **/

    public class SpinLockDemo {

    AtomicReference atomicReference = new AtomicReference<>();

    public void myLock(){

    Thread thread = Thread.currentThread();

    System.out.println(thread.getName() + "\t come in !");

    while (!atomicReference.compareAndSet(null,thread)){

    // System.out.println("我转!我转!");

    }

    }

    public void myUnLock(){

    Thread thread = Thread.currentThread();

    atomicReference.compareAndSet(thread,null);

    System.out.println(thread.getName() + "\t myUnLock !");

    }

    public static void main(String[] args) throws InterruptedException {

    SpinLockDemo demo = new SpinLockDemo();

    new Thread(() ->{

    demo.myLock();

    try {

    TimeUnit.SECONDS.sleep(5);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    demo.myUnLock();

    },"AA").start();

    TimeUnit.SECONDS.sleep(1);

    new Thread(() ->{

    demo.myLock();

    demo.myUnLock();

    },"BB").start();

    }

    }

    独占锁(写锁),共享锁(读锁),互斥锁

    /**

    * @ClassName ReadWriteLockDemo

    * @Description 互斥锁

    *

    * 多个线程同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源时,应该可以同时进行

    * 但是如果有一个线程尝试去写共享资源时,就不应该有其他的线程去读或者写

    * 小总结: 读-读 能共存

    * 读-写 不能共存

    * 写-写 不能共存

    **/

    class MyCache{

    private volatile Map map = new HashMap<>();

    private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();

    public void put(String key, Object value) {

    rwLock.writeLock().lock();

    try {

    System.out.println(Thread.currentThread().getName() + "\t 正在写入: " + key);

    try {

    TimeUnit.MILLISECONDS.sleep(300);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    map.put(key, value);

    System.out.println(Thread.currentThread().getName() + "\t 写入完成 ");

    }catch (Exception e){

    }finally {

    rwLock.writeLock().unlock();

    }

    }

    public void get(String key) {

    rwLock.readLock().lock();

    try {

    System.out.println(Thread.currentThread().getName() + "\t 正在读取");

    try {

    TimeUnit.MILLISECONDS.sleep(300);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println(Thread.currentThread().getName() + "\t 读取完成: " + map.get(key));

    }catch (Exception e){

    }finally {

    rwLock.readLock().unlock();

    }

    }

    }

    public class ReadWriteLockDemo {

    public static void main(String[] args) {

    MyCache myCache = new MyCache();

    for(int i = 1; i <= 5; i++){

    final int ii = i;

    new Thread(()-> myCache.put(ii + "", ii + "")

    ,String.valueOf(i)).start();

    }

    for(int i = 1; i <= 5; i++){

    final int ii = i;

    new Thread(()-> myCache.get(ii + "")

    ,String.valueOf(i)).start();

    }

    }

    }

    本文地址:https://blog.csdn.net/qq_38854914/article/details/107379037

    如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

    展开全文
  • 可重入锁和不可重入锁的区别

    万次阅读 2020-10-22 21:40:16
    不可重入锁示例(同一个线程不可以重入上锁后的代码段) 如下是一个不可重入锁的逻辑过程,会发现执行main方法控制台会打印执行doJob方法前,然后就会一直线程阻塞,不会打印执行doJob方法过程中,原因在于第一次上锁...

    不可重入锁示例(同一个线程不可以重入上锁后的代码段)

    如下是一个不可重入锁的逻辑过程,会发现执行main方法控制台会打印执行doJob方法前,然后就会一直线程阻塞,不会打印执行doJob方法过程中,原因在于第一次上锁后,由于没有释放锁,因此执行第一次lock后isLocked = true,这个时候调用doJob()内部又一次调用了lock()由于上个线程将isLocked = true,导致再次进入的时候就进入死循环。导致线程无法执行System.out.println("执行doJob方法过程中");这行代码,因此控制台只能打印执行doJob方法前。这种现象就造成了不可重入锁

    public class Count{
        MyLock lock = new MyLock();
    
        public static void main(String[] args) throws InterruptedException {
            new Count().doSomeThing(); // 示例的main方法
        }
        public void doSomeThing() throws InterruptedException {
            lock.lock(); // 第一次上锁
            System.out.println("执行doJob方法前");
            doJob(); // 方法内会再次上锁
            lock.unlock(); // 释放第一次上的锁
        }
        public void doJob() throws InterruptedException {
            lock.lock();
            System.out.println("执行doJob方法过程中");
            lock.unlock();
        }
    }
    
    /**
     * 自定义锁
     */
    class MyLock{
        private boolean isLocked = false;
        public synchronized void lock() throws InterruptedException{
            while(isLocked){
                wait();
            }
            isLocked = true; // 线程第一次进入后就会将器设置为true,第二次进入是就会由于where true进入死循环
        }
        public synchronized void unlock(){
            isLocked = false;   // 将这个值设置为false目的是释放锁
            notify();           // 接触阻塞
        }
    }
    

    可重入锁示例(同一个线程可以重入上锁的代码段,不同的线程则需要进行阻塞)

    java的可重入锁有:ReentrantLock(显式的可重入锁)synchronized(隐式的可重入锁)

    可重入锁诞生的目的就是防止上面不可重入锁的那种情况,导致同一个线程不可重入上锁代码段。

    目的就是让同一个线程可以重新进入上锁代码段。

    设计可重入锁的示例代码

    public class MyReentrantLock {
        boolean isLocked = false;   // 默认没有上锁
        Thread lockedBy = null; // 记录阻塞线程
        int lockedCount = 0;    // 上锁次数计数
    
        /**
         * 上锁逻辑
         */
        public synchronized void lock() throws InterruptedException {
            Thread thread = Thread.currentThread();
            // 上锁了 并且 如果是同一个线程则放行,否则其它线程需要进入where循环进行等待
            while (isLocked && lockedBy != thread) { 
                wait();
            }
            isLocked = true; // 第一次进入就进行上锁
            lockedCount++; // 上锁次数计数
            lockedBy = thread; // 当前阻塞的线程
        }
    
        /**
         * 释放锁逻辑
         */
        public synchronized void unlock() {
            if (Thread.currentThread() == this.lockedBy) {
                lockedCount--; // 将上锁次数减一
                if (lockedCount == 0) {// 当计数为0,说明所有线程都释放了锁
                    isLocked = false; // 真正的将释放了所有锁
                    notify();
                }
            }
        }
    }
    
    展开全文
  • 可重入和不可重入

    2019-02-07 09:19:46
    重入:可以重新进入,意思是在执行时,因为任务调动中断,再次重新进入继续执行,对其结果没有...可重入锁和不可重入锁 可重入函数和不可重入函数 函数当中只要有static变量,那么函数就是一个不可重入的函数。 ...
  • 可重入函数与不可重入函数的特点2.举例说明 1.可重入函数与不可重入函数的特点 那么什么是可重入函数呢? 所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时不必担心数据 是否会出错。 不可重入...
  • 锁:把需要的代码块,资源或数据锁上,只允许一个线程去操作,保证了并发时共享...下面我们以自旋锁设计一个不可重入锁/* 不可重入锁 */public class NRSpinLock implements Ilock{private AtomicReference currL...
  • 什么是不可重入锁?手写不可重入锁手写可重入锁juc包下的可重入锁 什么是可重入锁? 当某个线程试图获取一个自己已经持有的锁时,那么会立刻获得这个锁,不用等待,可以理解为这个锁可以继承。 同时这个锁的计数器也...
  • 前言最近在用Apache的Zookeeper客户端库Curator,Curator实现了一套的分布式锁,有可重入和不可重入,想起其实在单机环境下,Java提供的synchronized 和 ReentrantLock的锁工具,这两个都是可重入锁,所以可重入锁和...
  • Java 中可重入锁、不可重入锁的测试可重入锁指在同一个线程在外层方法获取锁的时候,进入内层方法会自动获取锁。为了避免死锁的发生,JDK 中基本都是可重入锁。下面我们来测试一下 synchronized 和java.util....
  • static:修饰全局变量,函数 改变作用域 修饰 局部变量 生命周期随进程 volatile: ...不可重入函数:一旦一个函数重入之后,就有可能造成数据二义问题或逻辑混乱 基准:在一个函数中是否对一个全局...
  • 不可重入函数  1.1. 什么是不可重入函数  a.在实时系统的设计中,经常会出现多个任务调用同一个函数的情况。如果有一个函数不幸被设计成为不可重入这样:那么不同任务调用这个函数时可能修改其他任务调用这个...
  • 关注、星标公众号,不错过精彩内容素材来源:网络编辑整理:strongerHuang一、什么是可重入函数与不可重入函数?可重入和不可重入函数主要用于多任务环境中,一个可重入的函数简单来说就...
  • 可重入锁 不可重入锁 在Java 5.0中,增加了一个新功能以增强内部锁定功能,称为可重入锁定。 在此之前,“同步”和“易失性”是实现并发的手段。 public synchronized void doAtomicTransfer(){ //enter ...
  • 主要介绍了Linux 中可重入函数与不可重入函数详解的相关资料,需要的朋友可以参考下
  • 可重入函数和不可重入函数 作为一个编程人员,一定要有可重入和不可重入概念,但工作中发现的现象让我大跌眼镜——很多人没听说过!!!亡羊补牢,为时不晚,现在在脑子中种下这颗概念种子也不迟。为什么说一定要有...
  • 可重入锁和不可重入

    万次阅读 2018-07-27 22:16:09
    可重入锁和不可重入锁 概念区分 当一个线程获得当前实例的锁lock,并且进入了方法A,该线程在方法A没有释放该锁的时候,是否可以再次进入使用该锁的方法B? 不可重入锁:在方法A释放锁之前,不可以再次进入方法B ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,727
精华内容 2,290
关键字:

可重入不可重入