`
echozhjun
  • 浏览: 47852 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java多线程及线程池小结

阅读更多
最近在学习线程池的东西,前面有篇文章《线程池的设计原则》,当然大多都是参考别人的思想。然后发现自己多线程真的写的太少了。现在来补充基础知识咯。。。 

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中有很多和多线程相通的地方。比如非阻塞和多线程,当然,他们不是一个意思。

分享到:
评论

相关推荐

    java线程详解

    八、线程同步小结 Java线程:线程的交互 Java线程:线程的调度-休眠 Java线程:volatile关键字 Java线程:新特征-线程池 一、固定大小的线程池 二、单任务线程池 三、可变尺寸的线程池 四、延迟连接池 五、...

    突破JAVA万人面试,懂多线程者得天下.zip

    目录网盘文件永久链接 01课程安排av 02什么是并发和并行av ...08线程创建小结av 09线程生命周期avi 10.线程安全问题什么是线程安全avi 11线程安全同题问题分析avi 12线程安全问题线程安全问题演示avi ...............

    Java基础知识点总结.docx

    Java数组与集合小结 305 递归 309 对象的序列化 310 Java两种线程类:Thread和Runnable 315 Java锁小结 321 java.util.concurrent.locks包下常用的类 326 NIO(New IO) 327 volatile详解 337 Java 8新特性 347 Java...

    Java优化编程(第2版)

    第12章 java多线程技术与应用性能优化 12.1 java多线程技术 12.1.1 进程与线程 12.1.2 线程的生命周期 12.2 并行任务与性能 12.2.1 并行任务与多线程 12.2.2 并行任务与死锁 12.3 线程池技术与应用性能优化 12.3.1 ...

    Java SE实践教程 pdf格式电子书 下载(四) 更新

    感谢大家的支持,我终于升级了,上传限制得到提升,所以把资源整合下!希望大家一如既往 Java SE实践教程 pdf格式电子书 下载(一) 更新 ...Java SE实践教程 pdf格式电子书 下载(二) 更新 ...13.4 小结 387

    疯狂JAVA讲义

    1.2 Java的竞争对手及各自优势 4 1.2.1 C#简介和优势 4 1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6 1.3.2 Java程序的运行机制和JVM 6 1.4 开发...

    Java SE实践教程 源代码 下载

    1.3 小结 35 第2章 对象无处不在——面向对象的基本概念 37 2.1 讲解 38 2.1.1 什么是面向对象 38 2.1.2 面向对象的基本概念 38 2.1.3 Java对面向对象的支持 41 2.2 练习 42 2.2.1 JavaBeans技术开发可重用...

    Java SE实践教程 pdf格式电子书 下载(一) 更新

    感谢大家的支持,我终于升级了,上传限制得到提升,所以把资源整合下!希望大家一如既往 Java SE实践教程 pdf格式电子书 下载(一) 更新 ...Java SE实践教程 pdf格式电子书 下载(二) 更新 ...13.4 小结 387

    【并发编程】 — Runnable、Callable、Future和FutureTask之间的关系

    Callable实现多线程2.2 线程池+Future+Callable 实现多线程3 Runnable、Callable、Future和FutureTask之间的关系3.1 整体关系介绍3.2 简单看一下源码3.3 四者关系小结 源码地址:...

    java范例开发大全源代码

     实例127 一个文件变成多个小文件 178  实例128 多个小文件合成一个文件 181  实例129 统计指定文件中的字符个数 183  实例130 对象的序列化与反序列化 185  实例131 同时显示多个文件 187  实例132...

    Linux多线程服务端编程:使用muduo C++网络库

    1.13心得与小结. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 26 1.14Observer 之谬. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 第2章线程同步精要 2.1互斥器...

    java范例开发大全

    第13章 多线程编程(教学视频:121分钟) 405 13.1 多线程的五种基本状态 405 实例222 启动线程 405 实例223 参赛者的比赛生活(线程休眠唤醒) 407 实例224 资源搜索并下载(线程等待和通报) 410 实例225 模拟淘宝...

    Java范例开发大全 (源程序)

     第13章 多线程编程(教学视频:121分钟) 405  13.1 多线程的五种基本状态 405  实例222 启动线程 405  实例223 参赛者的比赛生活(线程休眠唤醒) 407  实例224 资源搜索并下载(线程...

    java范例开发大全(pdf&源码)

    第13章 多线程编程(教学视频:121分钟) 405 13.1 多线程的五种基本状态 405 实例222 启动线程 405 实例223 参赛者的比赛生活(线程休眠唤醒) 407 实例224 资源搜索并下载(线程等待和通报) 410 实例225 模拟淘宝...

    Java范例开发大全(全书源程序)

    第13章 多线程编程(教学视频:121分钟) 405 13.1 多线程的五种基本状态 405 实例222 启动线程 405 实例223 参赛者的比赛生活(线程休眠唤醒) 407 实例224 资源搜索并下载(线程等待和通报) 410 实例225 ...

    javaSE代码实例

    第16章 多线程——Java中的并发协作 343 16.1 线程的基本知识 343 16.1.1 多线程编程的意义 343 16.1.2 定义自己的线程 344 16.1.3 创建线程对象 345 16.1.4 启动线程 347 16.1.5 同时使用多个线程 ...

    JAVA程序设计教程

    内容小结.........................................................................................................................12 思考与练习............................................................

    Java CP/IP Socket编程

    4.1.1 Java 多线程..........78 4.1.2 服务器协议..........80 4.1.3 一客户一线程..........84 4.1.4 线程池..........86 4.1.5 系统管理调度:Executor接口..........89 4.2 阻塞和超时..........91 4.2.1 ...

    精通ANDROID 3(中文版)1/2

    11.1.5 解决多线程问题  11.1.6 有趣的超时  11.1.7 使用HttpURLConnection  11.1.8 使用AndroidHttpClient  11.1.9 使用后台线程(AsyncTask)  11.1.10 使用AsyncTask处理配置更改  11.1.11 使用...

    精通Android 3 (中文版)2/2

    11.1.5 解决多线程问题  11.1.6 有趣的超时  11.1.7 使用HttpURLConnection  11.1.8 使用AndroidHttpClient  11.1.9 使用后台线程(AsyncTask)  11.1.10 使用AsyncTask处理配置更改  11.1.11 使用...

Global site tag (gtag.js) - Google Analytics