时间不会有多个线程是活动的。与其他等效的 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();}}虽然打印了一些信息,但是看的不是非常清晰,这个线程池是如何工作的,我们来将休眠的时间调长10倍。Thread.sleep((int)(Math.random()*10000));再来看,会清楚看到只能执行4个线程。当执行完一个线程后,才会又执行一个新的线程,也就是说,我们将所有的线程提交后,线程池会等待执行完最后shutdown。我们也会发现,提交的线程被放到一个“无界队列里”。这是一个有序队列(BlockingQueue,这个下面会说到)。另外它使用了Executors的静态函数生成一个固定的线程池,顾名思义,线程池的线程是不会释放的,即使它是Idle。这就会产生性能问题,比如如果线程池的大小为200,当全部使用完毕后,所有的线程会继续留在池中,相应的内存和线程切换(while(true)+sleep循环)都会增加。如果要避免这个问题,就必须直接使用ThreadPoolExecutor()来构造。可以像通用的线程池一样设置“最大线程数”、“最小线程数”和“空闲线程keepAlive的时间”。 这个就是线程池基本用法。Semaphore一个计数信号量。从概念上讲,信号量维护了一个许可集合。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。例如,下面的类使用信号量控制对内容池的访问:这里是一个实际的情况,大家排队上厕所,厕所只有两个位置,来了10个人需要排队。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+"]进入厕所,有空位"