3

class Tester{

private boolean flag = true ;//设置标志位,初始时先生产

private Lock lock = new ReentrantLock();

private Condition condition = lock.newCondition(); //产生一个Condition对象

publicvoid Method1(){

lock.lock();

try{

while(!flag){

condition.await() ;

}

//Do sth

flag= false ; //改变标志位,表示可以取走

condition.signal();

}catch(InterruptedException e){

e.printStackTrace() ;

}finally{

lock.unlock();

}

}

public void Method2(){

lock.lock();

try{

while(flag){

condition.await() ;

}

//Do sth

flag= true ;//改变标志位,表示可以生产

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获取的互斥锁不仅互斥读写操作、写写操作,还互斥读读操作,而读读操作时不会带来数据竞争的,因此对对读读操作也互斥的话,会降低性能。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:核心池的大小。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;

maximumPoolSize:线程池最大线程数,表示在线程池中最多能创建多少个线程;

keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;

unit:参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:

[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:一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种选择:

[if !supportLists]l[endif]ArrayBlockingQueue;

[if !supportLists]l[endif]LinkedBlockingQueue;

[if !supportLists]l[endif]SynchronousQueue;

ArrayBlockingQueue使用较少,一般使用LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。

threadFactory:线程工厂,主要用来创建线程;

handler:表示当拒绝处理任务时的策略,有以下四种取值:

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容