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.

  • 相关阅读:
    Android基础笔记(十八)- Fragment
    fedora20配置静态ip
    读《编程之美》励志篇
    官方教程Stealth学习笔记(一)
    从头认识Spring-2.4 基于java的标准注解装配-@Inject-限定器@Named
    POJ2186 Popular Cows [强连通分量|缩点]
    HDU2767Proving Equivalences[强连通分量 缩点]
    POJ1236Network of Schools[强连通分量|缩点]
    [USACO14OPEN] Dueling GPS's[最短路建模]
    洛谷2448 无尽的生命[树状数组 离散化]
  • 原文地址:https://www.cnblogs.com/mabaishui/p/2956993.html
Copyright © 2011-2022 走看看