class Tester{
private boolean flag = true ;//設(shè)置標(biāo)志位,初始時先生產(chǎn)
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition(); //產(chǎn)生一個Condition對象
publicvoid Method1(){
lock.lock();
try{
while(!flag){
condition.await() ;
}
//Do sth
flag= false ; //改變標(biāo)志位,表示可以取走
condition.signal();
}catch(InterruptedException e){
e.printStackTrace() ;
}finally{
lock.unlock();
}
}
public void Method2(){
lock.lock();
try{
while(flag){
condition.await() ;
}
//Do sth
flag= true ;//改變標(biāo)志位,表示可以生產(chǎn)
condition.signal();
}catch(InterruptedException e){
e.printStackTrace() ;
}finally{
lock.unlock();
}
}
}
class Producer implements Runnable{
private Tester producerTester = null ;
public Producer(Tester producerTester){
this.producerTester = producerTester ;
}
public void run(){
boolean flag = true ;
for(int i=0;i<10;i++){
this.producerTester.Method1();
if(flag){
flag = false ;
}else{
flag = true ;
}
}
}
}
class Consumer implements Runnable{
private Tester consumerTester = null ;
public Consumer(Tester consumerTester){
this.consumerTester = consumerTester ;
}
public void run(){
for(int i=0;i<10;i++){
this.consumerTester.Method2() ;
}
}
}
public class ThreadCaseDemo{
public static void main(String args[]){
Tester tester = new Tester();
Producer pro = new Producer(tester) ;
Consumer con = new Consumer(tester) ;
new Thread(pro).start() ;
try{
Thread.sleep(500) ;
}catch(InterruptedException e){
e.printStackTrace() ;
}
new Thread(con).start() ;
}
}
讀寫鎖:
通過synchronized獲取的互斥鎖不僅互斥讀寫操作、寫寫操作,還互斥讀讀操作,而讀讀操作時不會帶來數(shù)據(jù)競爭的,因此對對讀讀操作也互斥的話,會降低性能。Java 5中提供了讀寫鎖,它將讀鎖和寫鎖分離,使得讀讀操作不互斥。
[if !supportLists]1[endif]線程池使用
包:java.uitl.concurrent.ThreadPoolExecutor
[if !supportLists]1.1[endif]線程池類型
public class ThreadPoolExecutor extendsAbstractExecutorService {
.....
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,longkeepAliveTime,TimeUnit unit, BlockingQueue workQueue);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,longkeepAliveTime,TimeUnit unit, BlockingQueueworkQueue,ThreadFactory threadFactory);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnitunit, BlockingQueue workQueue,RejectedExecutionHandlerhandler);
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,longkeepAliveTime,TimeUnit unit, BlockingQueueworkQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler);
...
}
corePoolSize:核心池的大小。在創(chuàng)建了線程池后,默認(rèn)情況下,線程池中并沒有任何線程,而是等待有任務(wù)到來才創(chuàng)建線程去執(zhí)行任務(wù),除非調(diào)用了prestartAllCoreThreads()或者prestartCoreThread()方法,從這2個方法的名字就可以看出,是預(yù)創(chuàng)建線程的意思,即在沒有任務(wù)到來之前就創(chuàng)建corePoolSize個線程或者一個線程。默認(rèn)情況下,在創(chuàng)建了線程池后,線程池中的線程數(shù)為0,當(dāng)有任務(wù)來之后,就會創(chuàng)建一個線程去執(zhí)行任務(wù),當(dāng)線程池中的線程數(shù)目達(dá)到corePoolSize后,就會把到達(dá)的任務(wù)放到緩存隊列當(dāng)中;
maximumPoolSize:線程池最大線程數(shù),表示在線程池中最多能創(chuàng)建多少個線程;
keepAliveTime:表示線程沒有任務(wù)執(zhí)行時最多保持多久時間會終止。默認(rèn)情況下,只有當(dāng)線程池中的線程數(shù)大于corePoolSize時,keepAliveTime才會起作用,直到線程池中的線程數(shù)不大于corePoolSize,即當(dāng)線程池中的線程數(shù)大于corePoolSize時,如果一個線程空閑的時間達(dá)到keepAliveTime,則會終止,直到線程池中的線程數(shù)不超過corePoolSize。但是如果調(diào)用了allowCoreThreadTimeOut(boolean)方法,在線程池中的線程數(shù)不大于corePoolSize時,keepAliveTime參數(shù)也會起作用,直到線程池中的線程數(shù)為0;
unit:參數(shù)keepAliveTime的時間單位,有7種取值,在TimeUnit類中有7種靜態(tài)屬性:
[if !supportLists]l[endif]TimeUnit.DAYS;//天
[if !supportLists]l[endif]TimeUnit.HOURS;//小時
[if !supportLists]l[endif]TimeUnit.MINUTES;//分鐘
[if !supportLists]l[endif]TimeUnit.SECONDS;//秒
[if !supportLists]l[endif]TimeUnit.MILLISECONDS;//毫秒
[if !supportLists]l[endif]TimeUnit.MICROSECONDS;//微妙
[if !supportLists]l[endif]TimeUnit.NANOSECONDS;//納秒
workQueue:一個阻塞隊列,用來存儲等待執(zhí)行的任務(wù),這個參數(shù)的選擇也很重要,會對線程池的運行過程產(chǎn)生重大影響,一般來說,這里的阻塞隊列有以下幾種選擇:
[if !supportLists]l[endif]ArrayBlockingQueue;
[if !supportLists]l[endif]LinkedBlockingQueue;
[if !supportLists]l[endif]SynchronousQueue;
ArrayBlockingQueue使用較少,一般使用LinkedBlockingQueue和Synchronous。線程池的排隊策略與BlockingQueue有關(guān)。
threadFactory:線程工廠,主要用來創(chuàng)建線程;
handler:表示當(dāng)拒絕處理任務(wù)時的策略,有以下四種取值: