Java多線程編程之Lock用法實例
鎖是控制多個線程對共享資源進行訪問的工具。通常,鎖提供了對共享資源的獨占訪問。一次只能有一個線程獲得鎖,對共享資源的所有訪問都需要首先獲得鎖。不過,某些鎖可能允許對共享資源并發(fā)訪問,如 ReadWriteLock(維護了一對相關(guān)的鎖,一個用于只讀操作,另一個用于寫入操作) 的讀寫鎖。
1、Lock提供了無條件的、可輪詢的、定時的、可中斷的鎖獲取操作,所有加鎖和解鎖的方法都是顯式的。
public interface Lock{ void lock(); //加鎖 //優(yōu)先考慮響應(yīng)中斷,而不是響應(yīng)鎖定的普通獲取或重入獲取 void lockInterruptibly() throws InterruptedException; boolean tryLock(); //可定時和可輪詢的鎖獲取模式 boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException; void unlock(); //解鎖 Condition newCondition(); }
2、ReentrantLock實現(xiàn)了lock接口,跟synchronized相比,ReentrantLock為處理不可用的鎖提供了更多靈活性。
3、使用lock接口的規(guī)范形式要求在finally塊中釋放鎖lock.unlock()。如果鎖守護的代碼在try塊之外拋出了異常,它將永遠不會被釋放。
以下模擬Lock用法:假設(shè)有兩個線程(A線程、B線程)去調(diào)用print(String name)方法,A線程負責(zé)打印'zhangsan'字符串,B線程負責(zé)打印'lisi'字符串。
1、當沒有為print(String name)方法加上鎖時,則會產(chǎn)生A線程還沒有執(zhí)行完畢,B線程已開始執(zhí)行,那么打印出來的name就會出現(xiàn)如下問題。
2、當為print(String name)方法加上鎖時,則會產(chǎn)生A執(zhí)行完畢后,B線程才執(zhí)行print(String name)方法,達到互斥或者說同步效果。
package com.ljq.test.thread; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 用Lock替代synchronized * * @author Administrator * */ public class LockTest { public static void main(String[] args) { new LockTest().init(); } private void init() { final Outputer outputer = new Outputer(); //A線程 new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output("zhangsan"); } } }).start(); //B線程 new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } outputer.output("lisi"); } } }).start(); } static class Outputer { Lock lock = new ReentrantLock(); /** * 打印字符 * * @param name */ public void output(String name) { int len = name.length(); lock.lock(); try { for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } finally { lock.unlock(); } } } }
相關(guān)文章
SpringBoot配置MyBatis-Plus實現(xiàn)增刪查改
本文主要介紹了SpringBoot配置MyBatis-Plus實現(xiàn)增刪查改,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-08-08Spring中的之啟動過程obtainFreshBeanFactory詳解
這篇文章主要介紹了Spring中的之啟動過程obtainFreshBeanFactory詳解,在refresh時,prepareRefresh后,馬上就調(diào)用了obtainFreshBeanFactory創(chuàng)建beanFactory以及掃描bean信息(beanDefinition),并通過BeanDefinitionRegistry注冊到容器中,需要的朋友可以參考下2024-02-02Spring boot如何通過@Scheduled實現(xiàn)定時任務(wù)及多線程配置
這篇文章主要介紹了Spring boot如何通過@Scheduled實現(xiàn)定時任務(wù)及多線程配置,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-12-12Springboot如何連接遠程服務(wù)器上的數(shù)據(jù)庫實踐
本文主要介紹了Springboot如何連接遠程服務(wù)器上的數(shù)據(jù)庫實踐,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04