Java核心知识点 --- 线程中如何创建锁和使用锁 Lock , 设计一个缓存系统
理論知識很枯燥,但這些都是基本功,學完可能會忘,但等用的時候,會發覺之前的學習是非常有意義的,學習線程就是這樣子的.?
1.如何創建鎖?
Lock lock = new ReentrantLock();
2.如何使用鎖?
可以參看Lock文檔,其使用格式如下:
class X {private final ReentrantLock lock = new ReentrantLock();// ...public void m() {lock.lock(); // block until condition holdstry {// ... method body} finally {lock.unlock()}}}在要用的方法前加上鎖,比如寫操作,然后在finally中將鎖打開.
這里,將前文java核心知識點學習----多線程并發之線程同步中的代碼改用Lock實現數據同步,改寫代碼如下:
package com.amos.concurrent;import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;/*** @ClassName: LockTest* @Description: Lock學習* @author: amosli* @email:hi_amos@outlook.com* @date Apr 22, 2014 1:48:36 AM*/ public class LockTest {public static void main(String[] args) {new LockTest().init();}private void init() {final OutPuter outPuter = new OutPuter();// 新建一個線程new Thread(new Runnable() {public void run() {while (true) {// 休息10mstry {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}outPuter.output("hi_amos");// 輸出}}}).start();new Thread(new Runnable() {public void run() {while (true) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}outPuter.output("amosli");}}}).start();}static class OutPuter {// 方式1:使用synchronized關鍵字// public synchronized void output(String name) {// int length = name.length();// for (int i = 0; i < length; i++) {// System.out.print(name.charAt(i));// }// System.out.println();// }// 方式2:使用Lock鎖Lock lock = new ReentrantLock();public void output(String name) {lock.lock();// 加鎖int length = name.length();// 輸出name,逐個字節讀取,并輸出try {for (int i = 0; i < length; i++) {System.out.print(name.charAt(i));}System.out.println();} finally {lock.unlock();// 解鎖}}} }3.synchronized關鍵字與Lock的區別?
1).Lock是Java5中的新特性,更加面向對象.更類似于生活中的鎖.
2).Lock鎖一般需要手動開啟和關閉,而synchronized則不需要.
建議優先使用Lock.
4.注意事項:
1)多個讀鎖不互斥,讀鎖與寫鎖互斥,寫鎖與寫鎖互斥.
2)要實現兩個線程互斥,那么要將鎖加到同一個被訪問對象上.
3)如果你的代碼修改數據,只能有一個人在寫,且不能同時讀取,那就上寫鎖,總之,讀的時候用讀鎖,寫的時候用寫鎖!
?
5.設計一個緩存系統
什么是緩存系統??就是看本地是否已經緩存過此數據,如果已經緩存過,那就直接拿來用;如果沒有緩存過,那就查詢數據庫.
下面看代碼:
private Map<String, Object> cache = new HashMap<String, Object>();public synchronized Object getData(String key){Object object = cache.get(key);if (object==null) {object = "1323";//實際是去queryDB();}return object;}這里其實是一個超級簡單的緩存系統,原理就是:第一次訪問的時候把值存入到cache中,第二次訪問時,先去看cache中是否有值如果有值,那么就直接去取值,而不是從數據庫中去取.
為什么要加上synchronized? 這是為了保持數據互斥,訪問的時候不相互影響,因為其中有對object進行賦值操作,這是一個寫操作,所以最好加上鎖.
如何優化?
private ReadWriteLock rwl = new ReentrantReadWriteLock();public synchronized Object getData(String key){rwl.readLock();//read lockObject object = cache.get(key);try{if (object==null) {rwl.readLock().unlock();//釋放鎖rwl.writeLock().lock();//對寫加鎖try{object = "1323";//實際是去queryDB();}finally{rwl.writeLock().unlock();}}}finally{rwl.readLock().unlock();}return object;}?
上面的代碼運用到了剛學到的知識,對所有讀和寫進行加鎖,以保持線程間的互斥,要特別注意的是要在finally中把鎖打開,不管程序是否執行成功,因為如果不解鎖,那么程序將會產生死鎖,關于死鎖,將在接下來的文章中介紹.
轉載于:https://www.cnblogs.com/ncy1/p/9164474.html
總結
以上是生活随笔為你收集整理的Java核心知识点 --- 线程中如何创建锁和使用锁 Lock , 设计一个缓存系统的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javaee_SSH
- 下一篇: RPC远程过程