接下来逐一介绍
Executors主要方法说明
newFixedThreadPool(固定大小线程池)
创建一个可重用固定线程集合的线程池,以共享的无界队列方式来运行这些线程(只有要请求的过来,就会在一个队列里等待执行)。如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。
newCachedThreadPool(无界线程池,可以进行自动线程回收)
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。调用 execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。因此,长时间保持空闲的线程池不会使用任何资源。注意,可以使用 ThreadPoolExecutor 构造方法创建具有类似属性但细节不同(例如超时参数)的线程池。
newSingleThreadExecutor(单个后台线程)
创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。(注意,如果因为在关闭前的执行期间出现失败而终止了此单个线程,那么如果需要,一个新线程将代替它执行后续的任务)。可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。与其他等效的 newFixedThreadPool(1) 不同,可保证无需重新配置此方法所返回的执行程序即可使用其他的线程。
这些方法返回的都是ExecutorService对象,这个对象可以理解为就是一个线程池。
这个线程池的功能还是比较完善的。可以提交任务submit()可以结束线程池shutdown()。
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MyExecutor extends Thread { private int index; public MyExecutor(int i){ this.index=i; } public void run(){ try{ System.out.println("["+this.index+"] start...."); Thread.sleep((int)(Math.random()*1000)); System.out.println("["+this.index+"] end."); } catch(Exception e){ e.printStackTrace(); } } public static void main(String args[]){ ExecutorService service=Executors.newFixedThreadPool(4); for(int i=0;i<10;i++){ service.execute(new MyExecutor(i)); //service.submit(new MyExecutor(i)); } System.out.println("submit finish"); service.shutdown(); } }
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; public class MySemaphore extends Thread { Semaphore position; private int id; public MySemaphore(int i,Semaphore s){ this.id=i; this.position=s; } public void run(){ try{ if(position.availablePermits()>0){ System.out.println("顾客["+this.id+"]进入厕所,有空位"); }else{ System.out.println("顾客["+this.id+"]进入厕所,没空位,排队"); } position.acquire(); System.out.println("顾客["+this.id+"]获得坑位"); Thread.sleep((int)(Math.random()*1000)); System.out.println("顾客["+this.id+"]使用完毕"); position.release(); } catch(Exception e){ e.printStackTrace(); } } public static void main(String args[]){ ExecutorService list=Executors.newCachedThreadPool(); Semaphore position=new Semaphore(2); for(int i=0;i<10;i++){ list.submit(new MySemaphore(i+1,position)); } list.shutdown(); position.acquireUninterruptibly(2); System.out.println("使用完毕,需要清扫了"); position.release(2); } }
class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } }
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.ReentrantLock; public class MyReentrantLock extends Thread{ TestReentrantLock lock; private int id; public MyReentrantLock(int i,TestReentrantLock test){ this.id=i; this.lock=test; } public void run(){ lock.print(id); } public static void main(String args[]){ ExecutorService service=Executors.newCachedThreadPool(); TestReentrantLock lock=new TestReentrantLock(); for(int i=0;i<10;i++){ service.submit(new MyReentrantLock(i,lock)); } service.shutdown(); } } class TestReentrantLock{ private ReentrantLock lock=new ReentrantLock(); public void print(int str){ try{ lock.lock(); System.out.println(str+"获得"); Thread.sleep((int)(Math.random()*1000)); } catch(Exception e){ e.printStackTrace(); } finally{ System.out.println(str+"释放"); lock.unlock(); } } }
import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; public class MyBlockingQueue extends Thread { public static BlockingQueue<String> queue = new LinkedBlockingQueue<String>(3); private int index; public MyBlockingQueue(int i) { this.index = i; } public void run() { try { queue.put(String.valueOf(this.index)); System.out.println("{" + this.index + "} in queue!"); } catch (Exception e) { e.printStackTrace(); } } public static void main(String args[]) { ExecutorService service = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { service.submit(new MyBlockingQueue(i)); } Thread thread = new Thread() { public void run() { try { while (true) { Thread.sleep((int) (Math.random() * 1000)); if(MyBlockingQueue.queue.isEmpty()) break; String str = MyBlockingQueue.queue.take(); System.out.println(str + " has take!"); } } catch (Exception e) { e.printStackTrace(); } } }; service.submit(thread); service.shutdown(); } }
import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class MyCompletionService implements Callable<String> { private int id; public MyCompletionService(int i){ this.id=i; } public static void main(String[] args) throws Exception{ ExecutorService service=Executors.newCachedThreadPool(); CompletionService<String> completion=new ExecutorCompletionService<String>(service); for(int i=0;i<10;i++){ completion.submit(new MyCompletionService(i)); } for(int i=0;i<10;i++){ System.out.println(completion.take().get()); } service.shutdown(); } public String call() throws Exception { Integer time=(int)(Math.random()*1000); try{ System.out.println(this.id+" start"); Thread.sleep(time); System.out.println(this.id+" end"); } catch(Exception e){ e.printStackTrace(); } return this.id+":"+time; } }
import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestCountDownLatch { public static void main(String[] args) throws InterruptedException { // 开始的倒数锁 final CountDownLatch begin = new CountDownLatch(1); // 结束的倒数锁 final CountDownLatch end = new CountDownLatch(10); // 十名选手 final ExecutorService exec = Executors.newFixedThreadPool(10); for (int index = 0; index < 10; index++) { final int NO = index + 1; Runnable run = new Runnable() { public void run() { try { begin.await();//一直阻塞 Thread.sleep((long) (Math.random() * 10000)); System.out.println("No." + NO + " arrived"); } catch (InterruptedException e) { } finally { end.countDown(); } } }; exec.submit(run); } System.out.println("Game Start"); begin.countDown(); end.await(); System.out.println("Game Over"); exec.shutdown(); } }
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TestCyclicBarrier { // 徒步需要的时间: Shenzhen, Guangzhou, Shaoguan, Changsha, Wuhan private static int[] timeWalk = { 5, 8, 15, 15, 10 }; // 自驾游 private static int[] timeSelf = { 1, 3, 4, 4, 5 }; // 旅游大巴 private static int[] timeBus = { 2, 4, 6, 6, 7 }; static String now() { SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); return sdf.format(new Date()) + ": "; } static class Tour implements Runnable { private int[] times; private CyclicBarrier barrier; private String tourName; public Tour(CyclicBarrier barrier, String tourName, int[] times) { this.times = times; this.tourName = tourName; this.barrier = barrier; } public void run() { try { Thread.sleep(times[0] * 1000); System.out.println(now() + tourName + " Reached Shenzhen"); barrier.await(); Thread.sleep(times[1] * 1000); System.out.println(now() + tourName + " Reached Guangzhou"); barrier.await(); Thread.sleep(times[2] * 1000); System.out.println(now() + tourName + " Reached Shaoguan"); barrier.await(); Thread.sleep(times[3] * 1000); System.out.println(now() + tourName + " Reached Changsha"); barrier.await(); Thread.sleep(times[4] * 1000); System.out.println(now() + tourName + " Reached Wuhan"); barrier.await(); } catch (InterruptedException e) { } catch (BrokenBarrierException e) { } } } public static void main(String[] args) { // 三个旅行团 CyclicBarrier barrier = new CyclicBarrier(3); ExecutorService exec = Executors.newFixedThreadPool(3); exec.submit(new Tour(barrier, "WalkTour", timeWalk)); exec.submit(new Tour(barrier, "SelfTour", timeSelf)); //当我们把下面的这段代码注释后,会发现,程序阻塞了,无法继续运行下去。 exec.submit(new Tour(barrier, "BusTour", timeBus)); exec.shutdown(); } }
一下的例子也是网上比较流行的。
import static java.util.concurrent.TimeUnit.SECONDS; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; public class TestScheduledThread { public static void main(String[] args) { final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2); final Runnable beeper = new Runnable() { int count = 0; public void run() { System.out.println(new Date() + " beep " + (++count)); } }; // 1秒钟后运行,并每隔2秒运行一次 final ScheduledFuture beeperHandle = scheduler.scheduleAtFixedRate(beeper, 1, 2, SECONDS); // 2秒钟后运行,并每次在上次任务运行完后等待5秒后重新运行 final ScheduledFuture beeperHandle2 = scheduler.scheduleWithFixedDelay(beeper, 2, 5, SECONDS); // 30秒后结束关闭任务,并且关闭Scheduler scheduler.schedule(new Runnable() { public void run() { beeperHandle.cancel(true); beeperHandle2.cancel(true); scheduler.shutdown(); } }, 30, SECONDS); } }