java高并發(fā)程序設(shè)計(jì) - 網(wǎng)易云課堂
一、重入鎖
重入鎖是synchronized,Object.wait(),Object.notify()和替代品;
重入鎖的類是:java.util.concurrent.locks.ReentrantLock;
代碼如:
lock=new ReentrantLock();
lock.lock(); ? //加鎖
.....
lock.unlock();//解鎖
二、中斷響應(yīng)
lock=new ReentrantLock();
lock2=new ReentrantLock();
lock.lockInterruptibly(); ?//請(qǐng)求鎖
.....
lock2.interrupt(); ? //發(fā)出中斷信號(hào)
三、鎖申請(qǐng)等待限時(shí)
lock.tryLock();返回值是boolean類型;接收兩個(gè)參數(shù),一個(gè)表示等待時(shí)長(zhǎng),第二個(gè)表示記時(shí)單位;沒參數(shù)時(shí),是不等待;如果獲取了鎖,返回true;
與lock.tryLock()對(duì)應(yīng)的方法解鎖lock.unLock();
四、公平鎖
默認(rèn)情況下,鎖是非公平的;synchronized實(shí)現(xiàn)的鎖就是非公平的;
lock=new ReentrantLock(true);這就是公平鎖,公平鎖耗資源;
五、ReenreantLock的幾個(gè)重要方法:
lock();獲得鎖,如果鎖已經(jīng)被占用,則等待;
lockInterruptibly();獲得鎖,但優(yōu)先響應(yīng)中斷;
tryLock();嘗試獲得鎖,如果成功獲取,返回true;否則返回false;
tryLock(long time,TimeUnit unit);同上,只是在給定的時(shí)間內(nèi)嘗試去獲得鎖;
unlock();釋放鎖;
六、重入鎖的好搭檔,Condition條件
await();使當(dāng)前線程等待,同時(shí)釋放當(dāng)前的鎖;當(dāng)其它線程singal()之后,此線程會(huì)重新獲得鎖并繼續(xù)執(zhí)行。
awaitUninterruptibly();與await()方法基本想同,但不會(huì)在等待過(guò)程中響應(yīng)中斷;
singal()用于喚醒一個(gè)在等待中的線程;
七、信號(hào)量(semaphore)
信號(hào)量可以指定多個(gè)線程,同時(shí)訪問某一個(gè)資源;synchronized與重入鎖ReentrantLock,一次都只允許一個(gè)線程訪問一個(gè)資源;
其構(gòu)造方法:
public Semaphore(int permits);參數(shù)表示可以申請(qǐng)多少個(gè)許可;
public Semphore(int permits,boolean fair);第二個(gè)參數(shù)表示是否公平;
acquire()嘗試獲得一個(gè)準(zhǔn)入的許可,若無(wú)法獲得,則線程會(huì)等待,直到有線程釋放一個(gè)許可或者當(dāng)前線程被中斷;
acquireUninterruptibly()方法與acquire()方法類似,但不響應(yīng)中斷;
tryAcquire()嘗試獲得一個(gè)許可,如果成功返回true,失敗則返回false;
release()用于在線程訪問資源結(jié)束后,釋放一個(gè)許可;
八、讀寫分離鎖(ReadWriteLock)
ReentrantReadWriteLock
九、多線程控制工具類
倒計(jì)時(shí)器 CountDownLatch;
循環(huán)柵欄 CyclicBarrier;
十、線程阻塞工具類
LockSupport
十一、線程池
避免系統(tǒng)頻繁地創(chuàng)建和銷毀線程,可以讓創(chuàng)建的線程進(jìn)行復(fù)用。
JDK提供了一套Executor框架,其本質(zhì)就是一個(gè)線程池。
工廠方法:
newFixedThreadPool();返回一個(gè)固定線程數(shù)量的線程池。
newSingleThreadExecutor();返回只有一個(gè)線程的線程池;
newCachedThreadPool();
newSingleThreadScheduledExecutor();在給定的時(shí)間執(zhí)行某任務(wù)。如在某個(gè)固定的延時(shí)之后執(zhí)行,或者周期性執(zhí)行某個(gè)任務(wù);
十二、分而治之。Fork/Join框架
ForkJoinPool線程池
十三、JDK的并發(fā)容器
程序就是算法加數(shù)據(jù)結(jié)構(gòu);這些并發(fā)容器都是線程安全的。JDK提供的這些容器大部分在:java.util.concurrent包下。
并發(fā)集合:適合于多線程場(chǎng)合。
ConcurrentHashMap,一個(gè)線程安全的HashMap;
CopyOnWriteArrayList,用在讀多寫少的場(chǎng)合,是個(gè)線程安全的list,其性能好于Vector;
ConcurrentLinkedQueue,是個(gè)線程安全的LinkedList;
BlockingQueue,是個(gè)接口,JDK內(nèi)部通過(guò)鏈表(LinkedBlockingQueue)、數(shù)組(ArrayBlockingQueue)等方式實(shí)現(xiàn)了這個(gè)接口,表示阻塞隊(duì)列,適用于數(shù)據(jù)共享的通道;
另外,Collections工具類可以將任意集合包裝成線程安全的集合;如:
Map p=Collections.synchronizedMap(new HashMap());
ConcurrentSkipListMap的數(shù)據(jù)是有序的;