Lock接口简介

时间:2023-01-05 12:24:35

在Java多线程编程中,我们经常使用synchronized关键字来实现同步,控制多线程对变量的访问,来避免并发问题。

但是有的时候,synchronized关键字会显得过于沉重,不够灵活。synchronized 方法或语句的使用提供了对与每个对象相关的隐式监视器锁的访问,但却强制所有锁获取和释放均要出现在一个块结构中:当获取了多个锁时,它们必须以相反的顺序释放,且必须在与所有锁被获取时相同的词法范围内释放所有锁。

这个时候Lock出现。

Lock不是Java中的关键字而是 java.util.concurrent.locks 包中的一个接口。下面我们简单介绍一下Lock接口。

一、Lock接口简介

Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。

Lock相对于synchronized关键字而言更加灵活,你可以*得选择我你想要加锁的地方。当然更高的*度也带来更多的责任。

我们通常会在try...catch模块中使用lock关键字,在finally模块中释放锁。下面是示范代码。

    Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}

锁的锁定和释放如果在不同的模块时,需要谨慎编码,确保最后锁一定能够得到释放。

二、Lock接口中定义的方法

1、void lock()
获取锁。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态

2、void lockInterruptibly()
如果当前线程未被中断,则获取锁。

3、Condition newCondition()
返回绑定到此 Lock 实例的新 Condition 实例。

4、boolean tryLock()
仅在调用时锁为空闲状态才获取该锁。如果锁可用,则获取锁,并立即返回值 true。如果锁不可用,则此方法将立即返回值 false

5、boolean tryLock(long time, TimeUnit unit)
如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。

6、void unlock()
释放锁。在等待条件前,锁必须由当前线程保持。调用 Condition.await() 将在等待前以原子方式释放锁,并在等待返回前重新获取锁。

三、实现类ReentrantLock

Lock接口有三个实现类分别是ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock。后面两个是内部类。

第一个ReentrantLock,在我们平常使用中更为频繁。

ReentrantLock是一个可重入的互斥锁 Lock,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

ReentrantLock的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。否则此锁将无法保证任何特定访问顺序。也就是说这里可以设置锁的类型为公平锁还是非公平锁。但是,需要注意的是公平锁的情况下,也不能完全确保公平,它总是趋向公平的情况。

ReentrantLock类中还定义了Lock接口之外的方法,例如int getHoldCount() 、boolean hasQueuedThreads() 、boolean hasWaiters(Condition condition)等等,这些方法可以查询当前锁的状态。

四、代码使用

package com.test;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class TestLock { public static void main(String[] args) {
Lock lock = new ReentrantLock();
for(int i=0;i<5;i++){
ThreadPrintStar threadPrintStar = new TestLock().new ThreadPrintStar(lock);
threadPrintStar.start();
}
} /**
* 打印星星
* @author LKB
*
*/
class ThreadPrintStar extends Thread{
private Lock lock; public ThreadPrintStar(Lock lock) {
// TODO Auto-generated constructor stub
this.lock = lock;
} public void run(){
lock.lock();
try {
for(int i=0;i<5;i++){
if(i%2 == 0)
System.out.println("i = " + i + "+++" + Thread.currentThread().getName() +
" print: " + "☆☆");
else
System.out.println("i = " + i + "+++" + Thread.currentThread().getName() +
" print: " + "★★"); }
System.out.println();
System.out.println();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally {
lock.unlock();
}
}
} }

下面是程序运行结果,可以看到我们通过Lock实现了同步。

i = 0+++Thread-0 print: ☆☆
i = 1+++Thread-0 print: ★★
i = 2+++Thread-0 print: ☆☆
i = 3+++Thread-0 print: ★★
i = 4+++Thread-0 print: ☆☆ i = 0+++Thread-1 print: ☆☆
i = 1+++Thread-1 print: ★★
i = 2+++Thread-1 print: ☆☆
i = 3+++Thread-1 print: ★★
i = 4+++Thread-1 print: ☆☆ i = 0+++Thread-2 print: ☆☆
i = 1+++Thread-2 print: ★★
i = 2+++Thread-2 print: ☆☆
i = 3+++Thread-2 print: ★★
i = 4+++Thread-2 print: ☆☆ i = 0+++Thread-4 print: ☆☆
i = 1+++Thread-4 print: ★★
i = 2+++Thread-4 print: ☆☆
i = 3+++Thread-4 print: ★★
i = 4+++Thread-4 print: ☆☆ i = 0+++Thread-3 print: ☆☆
i = 1+++Thread-3 print: ★★
i = 2+++Thread-3 print: ☆☆
i = 3+++Thread-3 print: ★★
i = 4+++Thread-3 print: ☆☆

Lock接口简介的更多相关文章

  1. java多线程Lock接口简介使用与synchronized对比 多线程下篇(三)

    前面的介绍中,对于显式锁的概念进行了简单介绍 显式锁的概念,是基于JDK层面的实现,是接口,通过这个接口可以实现同步访问 而不同于synchronized关键字,他是Java的内置特性,是基于JVM的 ...

  2. Java基础知识强化之多线程笔记06:Lock接口 (区别于Synchronized块)

    1. 简介 我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式 ...

  3. SQLite3 C&sol;C&plus;&plus; 开发接口简介

    SQLite3 C/C++ 开发接口简介 1.0 总览 SQLite3是SQLite一个全新的版本,它虽然是在SQLite 2.8.13的代码基础之上开发的,但是使用了和之前的版本不兼容的数据库格式和 ...

  4. 显式锁(二)Lock接口与显示锁介绍

    一.显式锁简介    显式锁,这个叫法是相对于隐式锁synchronized而言的,加锁和解锁都要用户显式地控制.显示锁Lock是在Java5中添加到jdk的,同synchronized一样,这也是一 ...

  5. synchronized关键字,Lock接口以及可重入锁ReentrantLock

    多线程环境下,必须考虑线程同步的问题,这是因为多个线程同时访问变量或者资源时会有线程争用,比如A线程读取了一个变量,B线程也读取了这个变量,然后他们同时对这个变量做了修改,写回到内存中,由于是同时做修 ...

  6. 线程同步 Lock接口

    同步:★★★★★ 好处:解决了线程安全问题. 弊端:相对降低性能,因为判断锁需要消耗资源,产生了死锁. 定义同步是有前提的: 1,必须要有两个或者两个以上的线程,才需要同步. 2,多个线程必须保证使用 ...

  7. Java多线程&lpar;五&rpar; Lock接口&comma;ReentranctLock&comma;ReentrantReadWriteLock

    在JDK5里面,提供了一个Lock接口.该接口通过底层框架的形式为设计更面向对象.可更加细粒度控制线程代码.更灵活控制线程通信提供了基础.实现Lock接口且使用得比较多的是可重入锁(Reentrant ...

  8. jdk1&period;5多线程Lock接口及Condition接口

    jdk1.5多线程的实现的方式: jdk1.5之前对锁的操作是隐式的 synchronized(对象) //获取锁 { } //释放锁 jdk1.5锁的操作是显示的:在包java.util.concu ...

  9. Linux中的IO复用接口简介(文件监视?)

    I/O复用是Linux中的I/O模型之一.所谓I/O复用,指的是进程预先告诉内核,使得内核一旦发现进程指定的一个或多个I/O条件就绪,就通知进程进行处理,从而不会在单个I/O上导致阻塞. 在Linux ...

随机推荐

  1. Windows Phone 如何在程序中播放提示声音?

    在Windows Phone 中播放提示音可以使用 Microsoft.Xna.Framework.Audio 命名空间下的 SoundEffect 类.具体使用方法如下: 1. 根据声音文件路径创建 ...

  2. android 定制自己的日志工具

    最理想的情况是能够控制日志的打印,当程序处于开发阶段就让日志打印出来,当程序上线之后就把日志屏蔽掉. 例如打印一行WARN级别的日志就可以写成这样: LogUtil.w("TAG" ...

  3. 打开genesis时一直在等待,后出现Timeout in communication read解决方法

    运行输入:netsh winsock reset 然后重启电脑

  4. &lbrack;51NOD1126&rsqb;求递推序列的第n项&lpar;矩阵快速幂&rpar;

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1126 存在参数a,b为负数的情况.这时候要这么处理: 根据mo ...

  5. 前端性能监控系统ShowSlow

    作者:zhanhailiang 日期:2014-11-14 1. 简单介绍 ShowSlow是开源的前端性能监控系统,提供了下面功能: 前端性能指标数据收集功能:ShowSlow原生提供了数据收集工具 ...

  6. Got Stucked in C&plus;&plus; Static Library Loading&period;&period; for some time

    I used to load library using 1 single .dll file, so when I happen to do method calling between 2 pro ...

  7. 后端Nodejs利用node-xlsx模块读取excel

    后端Nodejs(利用node-xlsx模块) /** * Created by zh on 16-9-14. */ var xlsx = require("node-xlsx") ...

  8. Python开发简单爬虫(二)---爬取百度百科页面数据

    一.开发爬虫的步骤 1.确定目标抓取策略: 打开目标页面,通过右键审查元素确定网页的url格式.数据格式.和网页编码形式. ①先看url的格式, F12观察一下链接的形式;② 再看目标文本信息的标签格 ...

  9. Ex 5&lowbar;22 在此我们基于以下性质给出一个新的最小生成树算法&period;&period;&period;&lowbar;第九次作业

    (a)设环的顶点集为V, e(u,v)为权最重的边,若把V分成两部分V1,V2.其中V1包含u,V2包含v,因为V是一个环,因此,至少存在两条把u和v连接起来的边.因此,除了e之外,至少还存在另一条边 ...

  10. 《剑指offer》第五十五题(平衡二叉树)

    // 面试题55(二):平衡二叉树 // 题目:输入一棵二叉树的根结点,判断该树是不是平衡二叉树.如果某二叉树中 // 任意结点的左右子树的深度相差不超过1,那么它就是一棵平衡二叉树. #includ ...