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:表示当拒绝处理任务时的策略,有以下四种取值: