Java線程--鎖(下)

 

 

在上文中提到了Lock接口以及對象,使用它,很優雅的控制了競爭資源的安全訪問,可是這種鎖不區分讀寫,稱這種鎖爲普通鎖。爲了提升性能,Java提供了讀寫鎖,在讀的地方使用讀鎖,在寫的地方使用寫鎖,靈活控制,在必定程度上提升了程序的執行效率。java

 

Java中讀寫鎖有個接口java.util.concurrent.locks.ReadWriteLock,也有具體的實現ReentrantReadWriteLock,詳細的API能夠查看JavaAPI文檔。安全

 

下面這個例子是在文例子的基礎上,將普通鎖改成讀寫鎖,並添加帳戶餘額查詢的功能,代碼以下:併發

 

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.locks.ReadWriteLock; 
import java.util.concurrent.locks.ReentrantReadWriteLock; 

/** 
* Java線程:鎖 

* @author leizhimin 2009-11-5 10:57:29 
*/ 
public class Test { 
        public static void main(String[] args) { 
                //建立併發訪問的帳戶 
                MyCount myCount = new MyCount("95599200901215522", 10000); 
                //建立一個鎖對象 
                ReadWriteLock lock = new ReentrantReadWriteLock(false); 
                //建立一個線程池 
                ExecutorService pool = Executors.newFixedThreadPool(2); 
                //建立一些併發訪問用戶,一個信用卡,存的存,取的取,好熱鬧啊 
                User u1 = new User("張三", myCount, -4000, lock, false); 
                User u2 = new User("張三他爹", myCount, 6000, lock, false); 
                User u3 = new User("張三他弟", myCount, -8000, lock, false); 
                User u4 = new User("張三", myCount, 800, lock, false); 
                User u5 = new User("張三他爹", myCount, 0, lock, true); 
                //在線程池中執行各個用戶的操做 
                pool.execute(u1); 
                pool.execute(u2); 
                pool.execute(u3); 
                pool.execute(u4); 
                pool.execute(u5); 
                //關閉線程池 
                pool.shutdown(); 
        } 


/** 
* 信用卡的用戶 
*/ 
class User implements Runnable { 
        private String name;                //用戶名 
        private MyCount myCount;        //所要操做的帳戶 
        private int iocash;                 //操做的金額,固然有正負之分了 
        private ReadWriteLock myLock;                //執行操做所需的鎖對象 
        private boolean ischeck;        //是否查詢 

        User(String name, MyCount myCount, int iocash, ReadWriteLock myLock, boolean ischeck) { 
                this.name = name; 
                this.myCount = myCount; 
                this.iocash = iocash; 
                this.myLock = myLock; 
                this.ischeck = ischeck; 
        } 

        public void run() { 
                if (ischeck) { 
                        //獲取讀鎖 
                        myLock.readLock().lock(); 
                        System.out.println("讀:" + name + "正在查詢" + myCount + "帳戶,當前金額爲" + myCount.getCash()); 
                        //釋放讀鎖 
                        myLock.readLock().unlock(); 
                } else { 
                        //獲取寫鎖 
                        myLock.writeLock().lock(); 
                        //執行現金業務 
                        System.out.println("寫:" + name + "正在操做" + myCount + "帳戶,金額爲" + iocash +",當前金額爲" + myCount.getCash()); 
                        myCount.setCash(myCount.getCash() + iocash); 
                        System.out.println("寫:" + name + "操做" + myCount + "帳戶成功,金額爲" + iocash +",當前金額爲" + myCount.getCash()); 
                        //釋放寫鎖 
                        myLock.writeLock().unlock(); 
                } 
        } 


/** 
* 信用卡帳戶,可隨意透支 
*/ 
class MyCount { 
        private String oid;         //帳號 
        private int cash;             //帳戶餘額 

        MyCount(String oid, int cash) { 
                this.oid = oid; 
                this.cash = cash; 
        } 

        public String getOid() { 
                return oid; 
        } 

        public void setOid(String oid) { 
                this.oid = oid; 
        } 

        public int getCash() { 
                return cash; 
        } 

        public void setCash(int cash) { 
                this.cash = cash; 
        } 

        @Override 
        public String toString() { 
                return "MyCount{" + 
                                "oid='" + oid + '\'' + 
                                ", cash=" + cash + 
                                '}'; 
        } 
}ide

 

寫:張三正在操做MyCount{oid='95599200901215522', cash=10000}帳戶,金額爲-4000,當前金額爲10000 
寫:張三操做MyCount{oid='95599200901215522', cash=6000}帳戶成功,金額爲-4000,當前金額爲6000 
寫:張三他弟正在操做MyCount{oid='95599200901215522', cash=6000}帳戶,金額爲-8000,當前金額爲6000 
寫:張三他弟操做MyCount{oid='95599200901215522', cash=-2000}帳戶成功,金額爲-8000,當前金額爲-2000 
寫:張三正在操做MyCount{oid='95599200901215522', cash=-2000}帳戶,金額爲800,當前金額爲-2000 
寫:張三操做MyCount{oid='95599200901215522', cash=-1200}帳戶成功,金額爲800,當前金額爲-1200 
讀:張三他爹正在查詢MyCount{oid='95599200901215522', cash=-1200}帳戶,當前金額爲-1200 
寫:張三他爹正在操做MyCount{oid='95599200901215522', cash=-1200}帳戶,金額爲6000,當前金額爲-1200 
寫:張三他爹操做MyCount{oid='95599200901215522', cash=4800}帳戶成功,金額爲6000,當前金額爲4800 

Process finished with exit code 0性能

 

在實際開發中,最好在能用讀寫鎖的狀況下使用讀寫鎖,而不要用普通鎖,以求更好的性能。this

 

本文出自 「熔 巖」 博客.net

相關文章
相關標籤/搜索