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

为什么要使用线程池?

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

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 - 清洁工, 清扫厕所

package concurrency;

import java.util.Random;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ThreadPoolTest {

public static void main(String[] args) {

new ThreadPoolTest().test();

}

private void test() {

Toilet toilet = new Toilet();

boolean allowed = true;

for (int i=0; allowed; i++) {

People p = new People(i+"", toilet);

allowed = toilet.allowIn(p);

}

}

private class Toilet {

private volatile boolean cleaning = false;

private volatile int volume=0;

private final int CAPACITY = 100;

private volatile int peopleIn = 0;

private volatile int count = 0;

private Cleaner cleaner;

// 3 holes in his toilet.

private ExecutorService holes = Executors.newFixedThreadPool(3);

private Toilet() {

this.cleaner = new Cleaner(this);

}

private synchronized boolean allowIn(Runnable people) {

// If toilet is cleaning or 3 holes are taken, wait.

while (this.cleaning == true || this.peopleIn >= 3 ) {

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

// Only serves 100 people one day.

if (count > 100) {

this.holes.shutdown();

return false;

} else {

this.peopleIn(((People)people).name);

holes.submit(people);

return true;

}

}

private synchronized void enEn(String name, int v) {

this.volume += v;

System.out.println("People["+name+"] put in ["+v+"]. Toilet volume increases to ["+volume+"]");

// If the volume exceeds capacity, notify cleaner to clean.

if (this.volume > this.CAPACITY) {

this.notifyCleaner();

}

}

private void notifyCleaner() {

if (this.cleaning == false) {

System.out.println("Toilet volume full with ["+volume+"]. Notify cleaner.");

holes.submit(cleaner);

}

}

private synchronized void peopleIn(String name) {

System.out.println("People["+name+"] comes in.");

this.peopleIn ++;

this.count++;

}

private synchronized void peopleOut(String name) {

System.out.println("People["+name+"] comes out.");

this.peopleIn --;

this.notifyAll();

}

public synchronized void cleaning() {

this.cleaning = true;

}

public synchronized void cleaned() {

this.cleaning = false;

this.notifyAll();

}

}

// One toilet cleaner.

private class Cleaner implements Runnable {

private Toilet toilet;

private Cleaner(Toilet t) {

this.toilet = t;

}

@Override

public void run() {

toilet.cleaning();

System.out.println("Toilet Cleaning...");

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

this.toilet.volume = 0;

System.out.println("Toilet Clean done.");

toilet.cleaning = false;

toilet.cleaned();

}

}

private class People implements Runnable {

private Toilet toilet;

private String name;

private People(String name, Toilet t) {

this.toilet = t;

this.name = name;

}

@Override

public void run() {

System.out.println("People["+name+"] is en en en...");

try {

Thread.sleep(new Random().nextInt(500));

} catch (InterruptedException e) {

e.printStackTrace();

}

toilet.enEn(name, new Random().nextInt(11));

toilet.peopleOut(name);

}

}

}

你可能感兴趣的:(线程池,java模拟)