zoukankan      html  css  js  c++  java
  • 如何做到当某线程拿不到锁时不继续等待立刻退出?

    一、代码

    1、Worker类

    package com.leslie.test;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    public class Worker {
        private Object o = new Object();
        private ReentrantLock lock = new ReentrantLock();
    
        public void work1(String action) {
            System.out.println(action + " start");
            synchronized (o) {
                System.out.println(action + " work");
            }
            System.out.println(action + " over");
        }
    
        public void work2(String action) {
            System.out.println(action + " start");
            if (lock.tryLock()) {
                System.out.println(action + " work");
            }
            System.out.println(action + " over");
        }
    
        public void work3(String action) {
            System.out.println(action + " start");
            try {
                lock.lockInterruptibly();
                lock.lock();
                System.out.println(action + " work");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            System.out.println(action + " over");
        }
    }

    2、测试启动类

    package com.leslie.test;
    
    public class Tester {
        private static final Worker worker = new Worker();
        
        public static void testSynchronized(){
            Thread t1 = new Thread(){
                public void run() {worker.work1("A");}
            };
            Thread t2 = new Thread(){
                public void run() {worker.work1("B");}
            };
            Thread t3 = new Thread(){
                public void run() {worker.work1("C");}
            };
            Thread t4 = new Thread(){
                public void run() {worker.work1("D");}
            };
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
        public static void testTryLock(){
            Thread t1 = new Thread(){
                public void run() {worker.work2("A");}
            };
            Thread t2 = new Thread(){
                public void run() {worker.work2("B");}
            };
            Thread t3 = new Thread(){
                public void run() {worker.work2("C");}
            };
            Thread t4 = new Thread(){
                public void run() {worker.work2("D");}
            };
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
        public static void testLockInterruptibly(){
            Thread t1 = new Thread(){
                public void run() {worker.work3("A");}
            };
            Thread t2 = new Thread(){
                public void run() {worker.work3("B");}
            };
            Thread t3 = new Thread(){
                public void run() {worker.work3("C");}
            };
            Thread t4 = new Thread(){
                public void run() {worker.work3("D");}
            };
            t1.start();
            t2.start();
            t3.start();
            t4.start();
        }
        public static void main(String[] args) {
            testSynchronized();
        }
    }

    3、测试结果

    testSynchronized()执行结果:

    A start
    A work
    A over
    C start
    C work
    B start
    B work
    B over
    C over
    D start
    D work
    D over

    testTryLock()执行结果:

    B start
    B work
    B over
    D start
    D over
    A start
    A over
    C start
    C over

    testLockInterruptibly()执行结果:

    A start
    D start
    B start
    C start
    A work
    A over

    二、说明

    1、使用synchronized加锁时,拿不到锁的线程会一直等待直到得到锁才继续执行,并不会退出。

    2、使用lock.tryLock()的方式只能保证拿不到锁的线程不会执行tryLock(){}包括起来的代码,不在这个范围内的后续代码当拿到锁以后还会执行。

    3、使用lock.lockInterruptibly()时,拿不到锁的线程执行到这一句就会判断当前线程是否拥有lock,一旦发现lock已经锁住就结束线程,不会执行后续代码。

    补充:上面第3点不可取,虽然拿不到锁的线程不会继续执行下去,但这些线程会保持休眠状态(参考http://hi.baidu.com/gefforey520/item/202295fcf256e35fc8f3370a):

    Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.

    If the current thread already holds this lock then the hold count is incremented by one and the method returns immediately.

    If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens:

    • The lock is acquired by the current thread; or
    • Some other thread the current thread.

  • 相关阅读:
    eclipse修改web项目部署路径
    Jquery面试题
    23中设计模式之单例模式
    详细探讨单例模式
    java常用设计模式
    vue官网总结
    pytorch模型训练加速tricks
    element table显示滚动条
    vue中less文件全局引用
    vue路径别名无法识别,Cannot find module
  • 原文地址:https://www.cnblogs.com/mabaishui/p/2956993.html
Copyright © 2011-2022 走看看