Bootstrap

java.util.concurrent 包下常用的类

参考http://janeky.iteye.com/


package com.zf.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

/**
 * FutureTask  当有一个任务需要交给某个线程去处理时,可以用FutureTask
 * FutureTask实现了Runnable接口,因此可以通过Thread启动,或交给ExecutorService处理
 * 并提供了一个 get() 方法,返回任务执行的结果。在任务执行结束之前该方法阻塞,直到任务执行完,并返回结果。
 * 相当于同步了。
 * @author Administrator
 *
 */
public class FutureTaskTest {
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		ExecutorService pool = Executors.newCachedThreadPool();
		
		FutureTask<String> task = new FutureTask<String>(new Callable<String>() {

			@Override
			public String call() throws Exception {
				Thread.sleep(5000);
				return Thread.currentThread().getName();
			}
		});
		
		pool.execute(task);
		
		String result = task.get();
		
		
		System.out.println(result);  
		pool.shutdown();  //需要注意的是,如果线程池中还有多个方法在执行,该方法会在线程池中所有线程执行完毕后关闭。
                                  //如果要马上关闭线程池,可以用shutdownNow();方法来实现。
 }

}


BlockingQueue 文章推荐:http://blog.csdn.net/zlb824/article/details/7091814

package com.zf.thread;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 生产者 消费者  LinkedBlockingQueue 实现 
 * 该列队取出对象时,如果列队为空,就一直wait等待。直到列队非空。
 * 存入对象时,如果列队已满,就一直wait等待。直到列队非满  
 */
public class LinkedBlockingQueueTest {
	
	public int MAX_SIZE ;

	private BlockingQueue<String> queue ;
	
	public LinkedBlockingQueueTest(int max_size){
		this.MAX_SIZE = max_size;
		queue = new LinkedBlockingQueue<String>(MAX_SIZE);
	}
	
	public void buildProducer(){
		new Thread(new Producer(queue)).start();
	}
	
	
	public void buildConsumer(){ 
		new Thread(new Consumer(queue)).start();
	}
	
	/* 生产者 */
	class Producer implements Runnable{
		BlockingQueue<String> queue ; 
		public Producer(BlockingQueue<String> queue){
			this.queue = queue;
		}
		
		@Override
		public void run() {
			int i = 0 ;
			while(true){
				try {   
					System.out.println("即将存");
					queue.put( "包子"  + ++i);	//存
					System.out.println("生产了一个包子 ,包子数量:" + queue.size());
					if(queue.size() == MAX_SIZE){
						System.out.println("已满");
					}
				} catch (InterruptedException e) {  
					e.printStackTrace();
				}
			}
		}
	}
	
	/*消费者*/
	class Consumer implements Runnable{
		
		BlockingQueue<String> queue ; 
		public Consumer(BlockingQueue<String> queue){
			this.queue = queue;
		}
		
		@Override
		public void run() {
			try {
				System.out.println("即将取");
				queue.take();	//取
				if(queue.size() == 0){  
					System.out.println("取出了一个包子 ,包子数量:" + queue.size());
					System.out.println("已空");
				}
				Thread.sleep(1000);
			} catch (InterruptedException e) {  
				e.printStackTrace();
			}	
		}
	}
	
	public static void main(String[] args) {
		LinkedBlockingQueueTest pac = new LinkedBlockingQueueTest(5);
		pac.buildProducer();
		pac.buildConsumer();
	}

}

package com.zf.thread;

import java.util.Date;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


/**
 * ScheduledThreadPoolExecutor 定时任务线程池
 * 此类 类似于Timer ,但优于Timer
 * @author Administrator
 *
 */
public class ScheduledThreadPoolExecutorTest {

	public static void main(String[] args) {
		
		ScheduledThreadPoolExecutor poll = new ScheduledThreadPoolExecutor(1);
		
		poll.scheduleAtFixedRate(new Runnable() {
			@Override
			public void run() {
				System.out.println(new Date().toLocaleString());
			}
		}, 0 , 1, TimeUnit.SECONDS);
		
		
	}
	
}


package com.zf.thread;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * Semaphore 用于控制同一时间内   一个对象的某个方法 最多被n条线程同时访问
 * 在执行要限制的方法前先用 semaphore.acquire();方法判断是否已经到达边界,
 * 如果到达,就阻塞,否则执行方法,并信号量+1
 * 当要释放一个信号量时,用	semaphore.release() ; 方法
 * @author Administrator
 *
 */
public class SemaphoreTest {

	public static void main(String[] args) {
		final SemaphoreTest st = new SemaphoreTest();
		final BoundedHashSet<String> set = st.getSet();
		final ExecutorService poll = Executors.newCachedThreadPool();

		for (int i = 0; i < 5 ; i++) {
			poll.execute(new Runnable() {
				@Override
				public void run() {
					try {
						set.add(Thread.currentThread().getName());
					} catch (Exception e) {  
						e.printStackTrace();
					}
				}
			});
		}
		
		for (int i = 0; i < 5 ; i++) {
			poll.execute(new Runnable() {
				@Override
				public void run() {
					try {
						set.remove(Thread.currentThread().getName());
					} catch (Exception e) {  
						e.printStackTrace();
					}
				}
			});
		}

	}

	//返回一个同时只能有两个线程访问的set
	public BoundedHashSet<String> getSet(){
		return new BoundedHashSet<String>(2);
	}

	class BoundedHashSet<T>{

		private final Set<T> set ;

		private final Semaphore semaphore ;

		public BoundedHashSet(int bound){
			this.set = Collections.synchronizedSet(new HashSet<T>());  
			semaphore = new Semaphore(bound, true);
		}

		public void add(T t) throws Exception{
			System.out.println("即将添加 " + t);
			semaphore.acquire();	//判断是否已经到达边界,如果到了,就阻塞
			set.add(t);
			System.out.println("成功添加  " + t);
		}

		public void remove(T t)throws Exception{
			System.out.println("即将移除  " + t);
			if(set.remove(t)){
				System.out.println("成功移除 " + t);
				semaphore.release() ;	//释放掉一个信号量
			}
		}

	}


}


package com.zf.thread;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;

/**
 * 使用同步队列  SynchronousQueue 实现生产者消费者
 * 该列队里虽然是列队 ,但是列队里面的元素永远只会为1个。即:存一个,取一个,存一个,取一个 ,...
 * 存对象时,如果列队里面有元素,则wait等待,直到列队为空
 * 取元素时,如果列队为空,则wait等待,直到列队非空
 */
public class SynchronizedQueueTest {

	/* 生产者 */
	class Producer implements Runnable{

		private BlockingQueue<String> queue ;

		private final String[] objects = new String[]{
				"one" ,"two" ,"three"
		}	;

		public Producer(BlockingQueue<String> queue ){
			this.queue = queue;
		}

		@Override
		public void run() {
			try{
				for (String s : objects) {
					System.out.printf("%s即将放入到队列中\n" , s);
					queue.put(s);
					System.out.printf("%s已经放入到队列中\n" , s);
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}

	class Consumer implements Runnable{

		private BlockingQueue<String> queue ;

		public Consumer(BlockingQueue<String> queue ){
			this.queue = queue;
		}

		@Override
		public void run() {
			String obj = null;
			try {
				while(true){
					obj = queue.take();
					System.out.println("从队列中取出对象  " + obj);
					Thread.sleep(2000);
				}
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		BlockingQueue<String> queue = new SynchronousQueue<String>(); //同步队列
		SynchronizedQueueTest st = new SynchronizedQueueTest();
		new Thread(st.new Consumer(queue)).start();
		new Thread(st.new Producer(queue)).start();
	}

}

package com.zf.thread;

import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/*
 循环障碍CyclicBarrier,与CountDownLatch不同的是
该类是定义一个点。指定的线程到达某个点后,开始等待,直到所有的线程都到达这个点后。再一起继续向下执行。
(并且在所有线程到达该点后,可以实现某些操作。然后所有线程再继续向下执行)
在CyclicBarrier在释放等待线程之后 可以重用。
*/
public class TestCyclicBarrier {  
	  
    public static void main(String[] args) {  
      
        ExecutorService exec = Executors.newCachedThreadPool();       
        final Random random=new Random();  
          
        
        final CyclicBarrier barrier=new CyclicBarrier(4,new Runnable(){  
            @Override  
            public void run() {  
                System.out.println("大家都到齐了,开始happy去");  
            }}
        );  
          
        for(int i=0;i<4;i++){  
            exec.execute(new Runnable(){  
                @Override  
                public void run() {  
                    try {  
                        Thread.sleep(random.nextInt(1000));  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                    System.out.println(Thread.currentThread().getName()+"到了,其他哥们呢");  
                    try {  
                        barrier.await();//等待其他哥们  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    } catch (BrokenBarrierException e) {  
                        e.printStackTrace();  
                    }  
                    
                    System.out.println(Thread.currentThread().getName()+"准备去happy");  
                }});  
        }  
        exec.shutdown(); 
    }  
  
}  

package com.zf.thread;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * 延时队列 	DelayQueue 
 * 该队列是个优先级队列。被放入的对象需要实现Delayed接口。并指定该对象能被取出的延时时长。
 * 
 */
public class TestDelayQueue {

	public static void main(String[] args) throws Exception {
		DelayQueue<MyDelayed> queue = new DelayQueue<MyDelayed>();
		
		for(int i=1;i<=5;i++){  
			System.out.println("即将放入,延迟为:" + (i * 1000));     
			queue.add(new MyDelayed(i * 1000));  
		}  

		while(queue.size() > 0){
			System.out.println("即将取出");
			MyDelayed s= queue.take();	//延时时间未到就一直等待  
			if(s!=null){  
				System.out.println(System.currentTimeMillis()
						+ "  " + s.getDelayedtimt());// 当前时间 与 添加进去时设定的执行时间比较  
			}  
		}
	}
}

class MyDelayed  implements Delayed{

	long delayedtimt ;	//取出该对象的时间

	/**
	 * @param delayedtimt  延迟取出的时常
	 */
	public MyDelayed(long delayedtimt){	
		this.delayedtimt = System.currentTimeMillis() + delayedtimt; 
	}

	//因为该对象是要放到优先级队列里面去的。 所以要实现该方法,与队列里面的其他元素比较。
	@Override  
	public int compareTo(Delayed o) {
		return (int) (getDelay(TimeUnit.MILLISECONDS)
				- o.getDelay(TimeUnit.MILLISECONDS));
	}

	//返回与该对象关联的剩余延迟,在给定的时间单位。
	@Override
	public long getDelay(TimeUnit unit) {
		long sy =  delayedtimt - System.currentTimeMillis();
		return sy;
	}

	public long getDelayedtimt(){
		return delayedtimt;
	}
	
}

访问计数器。


package com.zf.test;

import java.util.concurrent.atomic.AtomicLong;

/* 线程安全计数器 
 * 类似功能的还有 	AtomicBoolean ab = new AtomicBoolean();
 * */

public class Test6 {
	
	final AtomicLong count = new AtomicLong(0); 
	//count.incrementAndGet()方法会让count的值 +1
	public void test(){
		System.out.println(count.incrementAndGet());
	}  
	public static void main(String[] args) {
		Test6 test = new Test6();
		test.test();
		test.test();
		test.test();
		test.test();
	}
	
}


;