Java多线程为什么使用线程池

 我来答
mytel_789
推荐于2017-09-25 · TA获得超过606个赞
知道小有建树答主
回答量:338
采纳率:0%
帮助的人:345万
展开全部
1:提高效率 创建好一定数量的线程放在池中,等需要使用的时候就从池中拿一个,这要比需要的时候创建一个线程对象要快的多。

2:方便管理 可以编写线程池管理代码对池中的线程统一进行管理,比如说系统启动时由该程序创建100个线程,每当有请求的时候,就分配一个线程去工作, 如果刚好并发有101个请求,那多出的这一个请求可以排队等候,避免因无休止的创建线程导致系统崩溃
niulu90
2010-07-02 · TA获得超过2472个赞
知道小有建树答主
回答量:1005
采纳率:0%
帮助的人:946万
展开全部
最近在学习线程池的东西,前面有篇文章《线程池的设计原则》,当然大多都是参考别人的思想。然后发现自己多线程真的写的太少了。现在来补充基础知识咯。。。
wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行.

以上是jdk api的说明,对照说明写个测试:
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public class Test extends Thread {

@Override
public void run() {
System.out.println("before wait!");
try {
synchronized (this) {
this.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
Thread.sleep(20000);
} catch (Exception e) {
System.out.println("interrupted!");
}
System.out.println("after wait!");
}

public synchronized void weakup() {
this.notify();
}
}

public class Main {

public static void main(String[] args) {
Test test = new Test();
test.start();
System.out.println("shit");
try {
Thread.sleep(2000);
} catch (Exception e) {
}
test.weakup();
try {
Thread.sleep(2000);
} catch (Exception e) {
}
test.interrupt();
System.out.println("shit");
}

wait和notify针对的是对象,而不是线程。因为这两个方法都是Object的方法。与线程无关。
所有的线程结束之后,程序才会结束。此处如果不sleep的话,有可能weakup会早于wait先调用。
执行interrupt()时,并不需要获取Thread实例的锁定.任何线程在任何时刻,都可以调用其他线程interrupt().当sleep中的线程被调用interrupt()时,就会放弃暂停的状态.并抛出InterruptedException.
interrupt()不会中断一个正在运行的线程。这一方法实际上完成的是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。
如果线程没有被阻塞,这时调用interrupt()将不起作用;否则,线程就将得到异常(该线程必须事先预备好处理此状况),接着逃离阻塞状态。
线程A在执行sleep,wait,join时,线程B调用A的interrupt方法,的确这一个时候A会有InterruptedException异常抛出来.但这其实是在sleep,wait,join这些方法内部会不断检查中断状态的值,而自己抛出的InterruptedException。
如果线程A正在执行一些指定的操作时如赋值,for,while,if,调用方法等,都不会去检查中断状态,所以线程A不会抛出InterruptedException,而会一直执行着自己的操作.当线程A终于执行到wait(),sleep(),join()时,才马上会抛出InterruptedException.
若没有调用sleep(),wait(),join()这些方法,或是没有在线程里自己检查中断状态自己抛出InterruptedException的话,那
InterruptedException是不会被抛出来的.
下面再看tomcat的线程池就比较清楚了:
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->class ControlRunnable implements Runnable {
ThreadPool p;
Thread t;
ThreadPoolRunnable toRun;
boolean shouldTerminate;
boolean shouldRun;
boolean noThData;
Object thData[] = null;

ControlRunnable(ThreadPool p) {
toRun = null;
shouldTerminate = false;
shouldRun = false;
this.p = p;
t = new Thread(this);
t.start();
noThData = true;
thData = null;
}

public void run() {
while (true) {
try {
synchronized (this) {
if (!shouldRun && !shouldTerminate) {
this.wait();
}
}
if (shouldTerminate) {
break;
}
try {
if (noThData) {
thData = toRun.getInitData();
noThData = false;
}
if (shouldRun) {
toRun.runIt(thData);
}
} catch (Throwable t) {
System.err.println("ControlRunnable Throwable: ");
t.printStackTrace();
shouldTerminate = true;
shouldRun = false;
p.notifyThreadEnd();
} finally {
if (shouldRun) {
shouldRun = false;
p.returnController(this);
}
}
if (shouldTerminate) {
break;
}
} catch (InterruptedException ie) {
}
}
}

public synchronized void runIt(ThreadPoolRunnable toRun) {
if (toRun == null) {
throw new NullPointerException("No Runnable");
}
this.toRun = toRun;
shouldRun = true;
this.notify();
}

public synchronized void terminate() {
shouldTerminate = true;
this.notify();
}

ControlRunnable线程类是线程池中的具体线程,线程构造函数中调用线程的start开始线程,到run方法里得到自己的锁然后wait,等待具体的动作调用:runIt,动作调用就可以notify线程了。里边将线程要做的具体工作委托给了ThreadPoolRunnable接口,用户要使用线程池,只用将自己的任务实现此接口即可。ThreadPoolRunnable的代码如下:
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->public interface ThreadPoolRunnable {
public Object[] getInitData();

public void runIt(Object thData[]);
}
另外,ThreadPool本身还运行了一个MonitorRunnable的线程,用来管理线程池。当(currentThreadCount - currentThreadsBusy) > maxSpareThreads,就会调用ControlRunnable类的terminate方法删除空闲线程,准备删除的线程是否空闲是通过shouldTerminate参数来判断。线程池采用Vector来存储当前空闲的线程。

接下来回去研究java nio包。网络编程也是自己一直都想去系统的学习的东西。而且,在java nio中有很多和多线程相通的地方。比如非阻塞和多线程,当然,他们不是一个意思。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
shy2850
2010-07-02 · TA获得超过6775个赞
知道大有可为答主
回答量:2505
采纳率:55%
帮助的人:1590万
展开全部
提高效率:

创建新的对象是一个比较复杂的过程,

可以在使用之初建立,避免使用过程中的等待。

不仅线程有池,字符串也是有的,

比如:

String s = "abcd";
String sr = "abcd";

在初始化sr的时候,虚拟机在池里寻找"abcd"字符串,找到了,
建立连接,这样,s和sr指向了同一个对象;

所以有:s==sr。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(1)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式