java多线程基本概述(九)——Lock(3)

java多线程基本概述(九)——Lock(3)

大家好,又见面了,我是全栈君。

Lock接口提供了三种获取锁的能力。可中断,不可中断,定时。api文档如下:

void lock()
Acquires the lock.//获取锁,
If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired.
//如果锁不可获取,那么由于线程调度器调度的意图,当前线程将被禁止,并且在锁被释放之前当前线程一致处于休眠状态。

 

void lockInterruptibly()throws InterruptedException
Acquires the lock unless the current thread is interrupted.
//如果当前线程没有被中断,那么将获得锁 Acquires the lock
if it is available and returns immediately. //如果锁可用则获取锁,并且快速返回。 If the lock is not available 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 interrupts the current thread, and interruption of lock acquisition is supported.
//其他某个线程中断当前线程,并且支持对锁获取的中断。 If the current thread: //如果当前线程 has its interrupted status set on entry to
this method; or
//在进入此方法时已经设置了该线程的中断状态;或者 is interrupted
while acquiring the lock, and interruption of lock acquisition is supported,
//在获取锁时被中断,并且支持对锁获取的中断 then InterruptedException is thrown and the current thread
's interrupted status is cleared.
//则将抛出 InterruptedException,并清除当前线程的已中断状态。

boolean tryLock()
Acquires the lock only if it is free at the time of invocation.
//仅在调用时锁为空闲状态才获取该锁。 Acquires the lock
if it is available and returns immediately with the value true.
//如果锁可用,则获取锁,并立即返回值 true。
If the lock is not available then this method will return immediately with the value false. //如果锁不可用,则此方法将立即返回值 false。 A typical usage idiom for this method would be: Lock lock = ...; if (lock.tryLock()) { try { // manipulate protected state } finally { lock.unlock(); } } else { // perform alternative actions } This usage ensures that the lock is unlocked if it was acquired, and doesn't try to unlock if the lock was not acquired.
//此用法可确保如果获取了锁,则会释放锁,如果未获取锁,则不会试图将其释放。 Returns: true if the lock was acquired and false otherwise

boolean tryLock(long time,TimeUnit unit) throws InterruptedException
Acquires the lock if it is free within the given waiting time and the current thread has not been interrupted.
//如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。 If the lock is available
this method returns immediately with the value true.
If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant
until one of three things happens: //如果锁可用,则此方法将立即返回值 true。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下三种情况之一前,该线程将一直处于休眠状态: The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported; or The specified waiting time elapses If the lock is acquired then the value
true is returned. //锁由当前线程获得;或者 其他某个线程中断当前线程,并且支持对锁获取的中断;或者 已超过指定的等待时间 如果获得了锁,则返回值 true。 If the current thread: has its interrupted status set on entry to this method; or is interrupted while acquiring the lock, and interruption of lock acquisition is supported, then InterruptedException is thrown and the current thread's interrupted status is cleared. If the specified waiting time elapses then the value false is returned. If the time is less than or equal to zero, the method will not wait at all.
//如果当前线程:在进入此方法时已经设置了该线程的中断状态;或者 在获取锁时被中断,并且支持对锁获取的中断,则将抛出 InterruptedException,并会清除当前线程的已中断状态。
//如果超过了指定的等待时间,则将返回值 false。如果 time 小于等于 0,该方法将完全不等待。
Returns:true if the lock was acquired and false if the waiting time elapsed before the lock was acquired
//如果获得了锁,则返回 true;如果在获取锁前超过了等待时间,则返回 false

package soarhu;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class TestNum {
    final ReentrantLock lock = new ReentrantLock(true);
    private Condition condition = lock.newCondition();
    void test() {
        lock.lock();//lock()不支持锁中断
        try {
            System.out.println("lock begin "+Thread.currentThread().getName());
            for (int i = 0; i < Integer.MAX_VALUE/20; i++) {
                Math.random();
            }
            System.out.println("lock end "+Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if( lock.isHeldByCurrentThread())
                lock.unlock();
        }
    }
}
public class Test{
    public static void main(String[] args) throws InterruptedException {
        TestNum t = new TestNum();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                t.test();
            }
        };
        Thread thread = new Thread(runnable);
        thread.setName("a");
        thread.start();
        Thread.sleep(500);
        Thread thread2 = new Thread(runnable);
        thread2.setName("b");
        thread2.start();
        thread2.interrupt();//发出中断指令
    }
}

输出结果:正常运行完毕,没有收到异常信息。

lock begin a
lock end a
lock begin b
lock end b

如果代码改为如下:那么会发生异常:

class TestNum {
    final ReentrantLock lock = new ReentrantLock(true);
    private Condition condition = lock.newCondition();
    void test() {
        try {
            lock.lockInterruptibly();
            System.out.println("lock begin "+Thread.currentThread().getName());
            for (int i = 0; i < Integer.MAX_VALUE/20; i++) {
                Math.random();
            }
            System.out.println("lock end "+Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if( lock.isHeldByCurrentThread())
                lock.unlock();
        }
    }
}

输出结果:

lock begin a
java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1220)
    at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
    at soarhu.TestNum.test(Test.java:12)
    at soarhu.Test$1.run(Test.java:32)
    at java.lang.Thread.run(Thread.java:745)
lock end a

Process finished with exit code 0

输出结果:可中断的异常能够接收到异常信息

class TestNum {
    final ReentrantLock lock = new ReentrantLock(true);
    private Condition condition = lock.newCondition();
    void test() {
        if(lock.tryLock()){
            try {
                System.out.println("lock begin "+Thread.currentThread().getName());
                for (int i = 0; i < Integer.MAX_VALUE/20; i++) {
                    Math.random();
                }
                System.out.println("lock end "+Thread.currentThread().getName());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if( lock.isHeldByCurrentThread())
                    lock.unlock();
            }
        }else{
            System.out.println("can't get lock,return as fast "+Thread.currentThread().getName());
        }
    }
}

输出结果:

lock begin a
can't get lock,return as fast b
lock end a

Process finished with exit code 0

分析:线程a获取锁时,锁是空闲的,那么会立即返回true.当线程b尝试获取锁时,发现锁正忙,那么就立即返回false。此锁是不可中断锁。

package soarhu;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class TestNum {
    final ReentrantLock lock = new ReentrantLock(true);
    private Condition condition = lock.newCondition();
    void test() {

            try {
                if(lock.tryLock(3000, TimeUnit.MILLISECONDS)){
   
   //1
                    System.out.println("lock begin "+Thread.currentThread().getName());
                    for (int i = 0; i < Integer.MAX_VALUE/20; i++) {
                        Math.random();
                    }
                    System.out.println("lock end "+Thread.currentThread().getName());
                }else{
                    System.out.println("can't get lock,return as fast "+Thread.currentThread().getName());//2
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if( lock.isHeldByCurrentThread())
                    lock.unlock();
            }

    }
}
public class Test{
    public static void main(String[] args) throws InterruptedException {
        TestNum t = new TestNum();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                t.test();
            }
        };
        Thread thread = new Thread(runnable);
        thread.setName("a");
        thread.start();
        //Thread.sleep(500);
        Thread thread2 = new Thread(runnable);
        thread2.setName("b");
        thread2.start();
        //thread2.interrupt(); //3
    }
}

输出结果:

lock begin a
lock end a
lock begin b
lock end b

分析:在第一行等待时间为3秒钟内,线程a获取到了锁,执行。然后b线程也尝试在3秒内获取锁,但在此时间内,a线程已运行完毕,b线程能正常获取锁。如果第一行改为  if(lock.tryLock(3, TimeUnit.MILLISECONDS)){
 那么输出结果为:

lock begin a
can't get lock,return as fast b
lock end a

Process finished with exit code 0

3毫秒的时间内a线程获取锁并正在执行任务,此时b线程进来锁正忙,于是立即被返回。如果把第三行注释取消掉,那么运行程序会抛出异常

输出结果:

lock begin a
java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireNanos(AbstractQueuedSynchronizer.java:1245)
    at java.util.concurrent.locks.ReentrantLock.tryLock(ReentrantLock.java:442)
    at soarhu.TestNum.test(Test.java:13)
    at soarhu.Test$1.run(Test.java:37)
    at java.lang.Thread.run(Thread.java:745)
lock end a

Process finished with exit code 0

可见 public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException 具有前面三种锁的能力。

转载于:https://www.cnblogs.com/soar-hu/p/6732252.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/108565.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • php lav,PotPlayer1.7.21129便携懒人包分享(madVR+LAV+ini设置)

    php lav,PotPlayer1.7.21129便携懒人包分享(madVR+LAV+ini设置)楼主,求助一个播放的问题,我播放这个视频会花屏,求解QQ截图20200213215751.jpg(235.51KB,下载次数:2)2020-2-1321:58上传视频信息如下:GeneralUniqueID:192839097181686327999562090253409942325(0x9113758C3C682128939D804…

  • pycharm激活码【注册码】

    pycharm激活码【注册码】,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • 手机:指纹识别基本原理图_手机指纹识别的工作原理

    手机:指纹识别基本原理图_手机指纹识别的工作原理指纹识别技术作为生物识别技术之一,指纹识别技术是通过取像设备读取指纹图像,然后在用识别软件提取指纹特征数据,最后在进行匹配识别算法得到结果,以确认指纹所有人身份的生物特征识别技术。指纹识别功能具体工

  • 配置企业网络中的三层交换机

    配置企业网络中的三层交换机

  • 小米手机解BL锁教程

    小米手机解BL锁教程1.找到设置,找到我的设备2.点击全部参数,点miui版本,点3下。3.返回,找到更多设置4.找到开发者选项5.找到设备定状态6.绑定账号和设备,关机,按开键加音量减,进去fast模式,链接电脑。7. 电脑打开下载解锁工具:点击链接下载将解锁工具解压缩,点击unlock.exe。7.解锁工具里登入可解锁的小米账号,同时将手机进入fastboot模式(关机状态下长按音量下键和电源键),用数据线连接电脑,提示已连接手机即可,若没有驱动点击图标安装即可。8.设备已解锁-解锁成功

  • 用Python读取CSV文件的5种方式

    用Python读取CSV文件的5种方式典型的数据集stocks.csv:一个股票的数据集,其实就是常见的表格数据。有股票代码,价格,日期,时间,价格变动和成交量。这个数据集其实就是一个表格数据,有自己的头部和身体。第一招:简单的读取我们先来看一种简单读取方法,先用csv.reader()函数读取文件的句柄f生成一个csv的句柄,其实就是一个迭代器,我们看一下这个reader的源码:喂给reader一个可迭代对象或者是文件的object,然后返回一个可迭代对象。首先读取csv文件,然后用csv.reader生成一个csv迭代器

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号