Javaマルチスレッド-新規フィーチャー-ロック(下)


ロックインタフェースおよびオブジェクトについては、前述したように、競合リソースへの安全なアクセスを優雅に制御していますが、このロックは読み書きを区別せず、通常のロックと呼ばれています.パフォーマンスを向上させるため、Javaは読み書きロックを提供し、読む場所では読み書きロックを使用し、書く場所では書き込みロックを使用し、柔軟に制御し、ある程度プログラムの実行効率を高めた.Javaの読み書きロックにはインタフェースjava.util.concurrent.locks.ReadWriteLockがあり、ReentrantReadWriteLockの実装もあり、詳細なAPIではJavaAPIドキュメントを表示できます.次の例は、本文の例に基づいて、通常のロックを読み書きロックに変更し、口座残高照会の機能を追加します.コードは以下の通りです.
package cn.thread;

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

/**
 *    
 * 
 * @author    
 * @version 1.0 2013-7-25   10:33:37
 */
public class WriteReadLockTest {
    public static void main(String[] args) {
        WriteReadLockTest test = new WriteReadLockTest();
        //          
        MyCount myCount = test.new MyCount("95599200901215522", 10000);
        //        
        ReadWriteLock lock = new ReentrantReadWriteLock(false);
        //        
        ExecutorService pool = Executors.newFixedThreadPool(2);
        //           ,     ,   ,   ,    
        User u1 = test.new User("  ", myCount, -4000, lock, false);
        User u2 = test.new User("    ", myCount, 6000, lock, false);
        User u3 = test.new User("    ", myCount, -8000, lock, false);
        User u4 = test.new User("  ", myCount, 800, lock, false);
        User u5 = test.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 + '}';
        }
    }
}
 :      MyCount{oid='95599200901215522', cash=10000}  ,   -4000,     10000
 :    MyCount{oid='95599200901215522', cash=6000}    ,   -4000,     6000
 :        MyCount{oid='95599200901215522', cash=6000}  ,   6000,     6000
 :      MyCount{oid='95599200901215522', cash=12000}    ,   6000,     12000
 :      MyCount{oid='95599200901215522', cash=12000}  ,   800,     12000
 :    MyCount{oid='95599200901215522', cash=12800}    ,   800,     12800
 :        MyCount{oid='95599200901215522', cash=12800}  ,   -8000,     12800
 :      MyCount{oid='95599200901215522', cash=4800}    ,   -8000,     4800
 :        MyCount{oid='95599200901215522', cash=4800}  ,     4800

実際の開発では、通常のロックではなく、読み書きロックを使用して、より良いパフォーマンスを追求することが望ましい.