Java 锁示例 - ReentrantLock

欢迎访问 Java Lock 示例教程. 通常在使用多线程环境时,我们使用 [同步用于线程安全]( / 社区 / 教程 / 线程安全-in-java)。

Java 锁定

java lock, java lock example, ReentrantLock in Java, java locks Most of the times, synchronized keyword is the way to go but it has some shortcomings that lead the way to inclusion of Lock API in Java Concurrency package. Java 1.5 Concurrency API came up with java.util.concurrent.locks package with Lock interface and some implementation classes to improve the Object locking mechanism. Some important interfaces and classes in Java Lock API are:

  1. 联合国 Lock:这是Lock API的基础接口. 它提供了同步关键字的所有特性,并增加了创建不同锁入条件的方法,提供了线程等待锁入的超时. 一些重要方法有:锁定()获取锁,解锁()释放锁,terLock()等待锁定一段时间,新条件()创建条件等
  2. ** 条件**:条件对象类似于对象等-通知模式,具有额外的功能来创建不同的等集. 一个条件对象总是由Lock对象所创造. 一些重要的方法是等待()类似于等待()和信号(),信号All()类似于通知()和通知All()方法.
  3. ** 读作Lock** : 它包含一对相联的锁,一个用于只读操作,另一个用于写作. 只要没有写作线程,读取的锁就可以被多条读取线程同时持有. 书写锁为独有.
  4. ReentrantLock:这是Lock接口使用最广泛的执行类. 此类以同步关键字类似的方式执行 Lock 接口. 除了Lock接口执行外,ReentrantLock还包含一些工具方法来得到线程控锁,线程等等待获得锁等. 同步块在性质上是再入的,即如果一个线程对被监视对象有锁,如果另一个同步块要求同一被监视对象有锁,则线程可以输入该代码块. 我认为这就是班名ReentrantLock的原因. 让我们用一个简单的例子来理解这个特征。 QQ 公共类测试{

公共同步 foo (- ) { (- ) 公共类测试{ (- ) (- ) (-) 公共同步 foo (- ) (-) (- ) 公共同步 foo (-) (- ) 公共同步 foo (-) (- ) (-) 公共同步 foo (- ) (- ) 公共同步测试项目上设有锁(- ) ,因此当它试图执行bar (-) 方法时,该线被允许执行 bar (-) 方法,因为它已经持有与同步对象 i.e 相同(此) 。 (单位:千美元) (英语)

Java 锁例 - Java 中的 ReentrantLock

现在让我们来看看一个简单的例子,我们将同步的关键字用Java Lock API代替,假设我们有一个资源类,其中有一定的操作,我们希望它是线程安全的,一些方法不需要线程安全。

 1package com.journaldev.threads.lock;
 2
 3public class Resource {
 4
 5    public void doSomething(){
 6    	//do some operation, DB read, write etc
 7    }
 8    
 9    public void doLogging(){
10    	//logging, no need for thread safety
11    }
12}

现在,假设我们有一个可运行类,我们将使用资源方法。

 1package com.journaldev.threads.lock;
 2
 3public class SynchronizedLockExample implements Runnable{
 4
 5    private Resource resource;
 6    
 7    public SynchronizedLockExample(Resource r){
 8    	this.resource = r;
 9    }
10    
11    @Override
12    public void run() {
13    	synchronized (resource) {
14    		resource.doSomething();
15    	}
16    	resource.doLogging();
17    }
18}

请注意,我正在使用同步区块来获取资源对象的锁。我们可能在课堂中创建了一个愚蠢的对象,并将其用于锁定目的。现在让我们看看如何使用 Java Lock API 并在没有使用同步关键字的情况下重写上面的程序。

 1package com.journaldev.threads.lock;
 2
 3import java.util.concurrent.TimeUnit;
 4import java.util.concurrent.locks.Lock;
 5import java.util.concurrent.locks.ReentrantLock;
 6
 7public class ConcurrencyLockExample implements Runnable{
 8
 9    private Resource resource;
10    private Lock lock;
11    
12    public ConcurrencyLockExample(Resource r){
13    	this.resource = r;
14    	this.lock = new ReentrantLock();
15    }
16    
17    @Override
18    public void run() {
19    	try {
20    		if(lock.tryLock(10, TimeUnit.SECONDS)){
21    		resource.doSomething();
22    		}
23    	} catch (InterruptedException e) {
24    		e.printStackTrace();
25    	}finally{
26    		//release lock
27    		lock.unlock();
28    	}
29    	resource.doLogging();
30    }
31
32}

正如你可以看到的那样,我正在使用 tryLock() 方法来确保我的线程只等待一定时间,如果它没有在对象上锁定,它只是登录和退出。

Java 锁定与同步

基于上述细节和程序,我们可以很容易地得出Java Lock和同步之间的差异。

Java Lock API提供更多的可见性和锁定选项,不像同步的线条可能终究等待锁定,我们可以使用 tryLock()来确保线条只等待特定时间. 2 同步代码更清洁,更容易维护,而使用 Lock,我们被迫尝试最终锁定以确保锁定释放,即使在 lock() 和 unlock() 方法调用之间投放了一些例外 3 同步块或方法只能覆盖一种方法,而我们可以在一种方法中获得锁定,并在另一种方法中释放 Lock API.( )4 同步关键字不会提供公平性,而我们可以在创建 ReentrantLock 对象时设置公平性,因此最长的等待线条

这就是Java Lock的例子,Java中的ReentrantLock和与同步关键字的比较分析。

Published At
Categories with 技术
Tagged with
comments powered by Disqus