JAVA多线程-线程池-实例模拟上厕所问题

JAVA多线程-线程池-实例模拟上厕所问题(三)


发表于(2012-11-10 01:06)  from  http://my.oschina.net/xpbug/blog/88259

为什么要使用线程池?

启动一个线程是一件很耗资源的事情, 启动线程需要跟底层操作系统打交道,为新线程开辟一个资源空间. 此外,一个进程中,线程过多,会耗尽资源,导致系统崩溃. 所以,重用和控制线程数量,是线程的必要知识.

Executors

J2ME中的java.util.concurrent.Executors就是一个线程执行器工厂,这个执行器可以管理线程池. Executors应该算是一个工厂,使用它类似newInstance的方法,可以创造出各种功能的ExecutorService(interface)实例. ExecutorService是Executor的继承接口.它的实例也就是线程执行器.

下面来看看Executors能产生什么功能的Executor实例.

newFixedThreadPool() - 创造一个管理固定数量线程的线程池.

newCachedThreadPool() - 创造一个管理非固定数量的线程池,线程一旦结束一段时间,则销毁.

newSingleThreadExecutor() - 产生一个单线程的执行器.

newSingleScheduledThreadExecutor() - 产生一个scheduled单线程执行器.

newScheduledThreadPool() - 创造一个scheduled线程的线程池.

有了Executor或者ExecutorService以后,怎么调用线程呢?

用例

一个厕所有3个,人们不停的进厕所做enen的事情.排量随机,蹲坑时间随机.  厕所的容量(capacity)为100, 当厕所的排量(volume)超过容量的时候, 通知清洁工来清洁. 清洁过程中不能再放新人进来. 厕所每天只服务100个人,然后停业.

本例中有4个类:

ThreadPool - main函数入口类.

Toilet - 厕所, 它使用一个具有3个线程处理能力的线程池来表达3个坑(holes)的概念.

People - 人, 排队上厕所

Cleaner - 清洁工, 清扫厕所

001 package concurrency;
002  
003 import java.util.Random;
004 import java.util.concurrent.ExecutorService;
005 import java.util.concurrent.Executors;
006  
007 public class ThreadPoolTest {
008      
009     public static void main(String[] args) {
010          new ThreadPoolTest().test();
011     }
012      
013     private void test() {
014         Toilet toilet = new Toilet();
015          
016         boolean allowed = true;
017         for (int i=0; allowed; i++) {
018             People p = new People(i+"", toilet);
019             allowed = toilet.allowIn(p);
020         }
021     }
022      
023     private class Toilet {
024         private volatile boolean cleaning = false;
025         private volatile int volume=0;
026         private final int CAPACITY = 100;
027         private volatile int peopleIn = 0;
028         private volatile int count = 0;
029         private Cleaner cleaner;
030         // 3 holes in his toilet.
031         private ExecutorService holes = Executors.newFixedThreadPool(3);
032          
033         private Toilet() {
034             this.cleaner = new Cleaner(this);
035         }
036         private synchronized boolean allowIn(Runnable people) {
037             // If toilet is cleaning or 3 holes are taken, wait.
038             while (this.cleaning == true || this.peopleIn >= 3 ) {
039                 try {
040                     this.wait();
041                 catch (InterruptedException e) {
042                     e.printStackTrace();
043                 }
044             }
045              
046             // Only serves 100 people one day.
047             if (count > 100) {
048                 this.holes.shutdown();
049                 return false;
050             else {
051                 this.peopleIn(((People)people).name);
052                 holes.submit(people);
053                 return true;
054             }
055         }
056          
057         private synchronized void enEn(String name, int v) {
058             this.volume += v;
059             System.out.println("People["+name+"] put in ["+v+"]. Toilet volume increases to ["+volume+"]");
060              
061             // If the volume exceeds capacity, notify cleaner to clean.
062             if (this.volume > this.CAPACITY) {
063                 this.notifyCleaner();
064             }
065         }
066  
067         private void notifyCleaner() {
068             if (this.cleaning == false) {
069                 System.out.println("Toilet volume full with ["+volume+"]. Notify cleaner.");
070                 holes.submit(cleaner);
071             }
072         }
073          
074         private synchronized void peopleIn(String name) {
075             System.out.println("People["+name+"] comes in.");
076             this.peopleIn ++;
077             this.count++;
078         }
079          
080         private synchronized void peopleOut(String name) {
081             System.out.println("People["+name+"] comes out.");
082             this.peopleIn --;
083             this.notifyAll();
084         }
085         public synchronized void cleaning() {
086             this.cleaning = true;
087              
088         }
089         public synchronized void cleaned() {
090             this.cleaning = false;
091             this.notifyAll();
092         }
093     }
094      
095     // One toilet cleaner.
096     private class Cleaner implements Runnable {
097         private Toilet toilet;
098         private Cleaner(Toilet t) {
099             this.toilet = t;
100         }
101  
102         @Override
103         public void run() {
104             toilet.cleaning();
105             System.out.println("Toilet Cleaning...");
106             try {
107                 Thread.sleep(2000);
108             catch (InterruptedException e) {
109                 e.printStackTrace();
110             }
111             this.toilet.volume = 0;
112             System.out.println("Toilet Clean done.");
113             toilet.cleaning = false;
114             toilet.cleaned();
115         }
116     }
117      
118     private class People implements Runnable {
119         private Toilet toilet;
120         private String name;
121         private People(String name, Toilet t) {
122             this.toilet = t;
123             this.name = name;
124         }
125  
126         @Override
127         public void run() {
128             System.out.println("People["+name+"] is en en en...");
129             try {
130                 Thread.sleep(new Random().nextInt(500));
131             catch (InterruptedException e) {
132                 e.printStackTrace();
133             }
134              
135             toilet.enEn(name, new Random().nextInt(11));
136             toilet.peopleOut(name);
137         }
138          
139     }
140  
141 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值