简单介绍: 创建线程有两种方式:继承Thread或实现Runnable。Thread实现了Runnable接口,提供了一个空的run()方法,所以不论是继承Thread还是实现Runnable,都要有自己的run()方法。
一个线程创建后就存在,调用start()方法就开始运行(执行run()方法),调用wait进入等待或调用sleep进入休眠期,顺利运行完毕或休眠被中断或运行过程中出现异常而退出。
wait和sleep比较:
sleep 方法属于Thread类中方法,表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢 复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep 的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程 就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及 以后的代码。
注意sleep()方法是一个静态方法,也就是说他只对当前对象有效,通过t.sleep()让t对象进入sleep,这样的做法是错误的,它只会是使当前线程被sleep 而不是t线程
wait 属于Object的成员方法,一旦一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程;如果线程拥有某个或 某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。wait()方法 也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生
InterruptedException,效果以及处理方式同sleep()方法
线程池简介:
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。
线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目,看一个例子:
假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线 程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建 50000而在处理请求时浪费时间,从而提高效率。
代码实现中并没有实现任务接口,而是把Runnable对象加入到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了
- package mine.util.thread;
- import java.util.LinkedList;
- import java.util.List;
- /**
- * 线程池类,线程管理器:创建线程,执行任务,销毁线程,获取线程基本信息
- */
- public final class ThreadPool {
- // 线程池中默认线程的个数为5
- private static int worker_num = 5;
- // 工作线程
- private WorkThread[] workThrads;
- // 未处理的任务
- private static volatile int finished_task = 0;
- // 任务队列,作为一个缓冲,List线程不安全
- private List<Runnable> taskQueue = new LinkedList<Runnable>();
- private static ThreadPool threadPool;
- // 创建具有默认线程个数的线程池
- private ThreadPool() {
- this(5);
- }
- // 创建线程池,worker_num为线程池中工作线程的个数
- private ThreadPool(int worker_num) {
- ThreadPool.worker_num = worker_num;
- workThrads = new WorkThread[worker_num];
- for (int i = 0; i < worker_num; i++) {
- workThrads[i] = new WorkThread();
- workThrads[i].start();// 开启线程池中的线程
- }
- }
- // 单态模式,获得一个默认线程个数的线程池
- public static ThreadPool getThreadPool() {
- return getThreadPool(ThreadPool.worker_num);
- }
- // 单态模式,获得一个指定线程个数的线程池,worker_num(>0)为线程池中工作线程的个数
- // worker_num<=0创建默认的工作线程个数
- public static ThreadPool getThreadPool(int worker_num1) {
- if (worker_num1 <= 0)
- worker_num1 = ThreadPool.worker_num;
- if (threadPool == null)
- threadPool = new ThreadPool(worker_num1);
- return threadPool;
- }
- // 执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
- public void execute(Runnable task) {
- synchronized (taskQueue) {
- taskQueue.add(task);
- taskQueue.notify();
- }
- }
- // 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
- public void execute(Runnable[] task) {
- synchronized (taskQueue) {
- for (Runnable t : task)
- taskQueue.add(t);
- taskQueue.notify();
- }
- }
- // 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
- public void execute(List<Runnable> task) {
- synchronized (taskQueue) {
- for (Runnable t : task)
- taskQueue.add(t);
- taskQueue.notify();
- }
- }
- // 销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁
- public void destroy() {
- while (!taskQueue.isEmpty()) {// 如果还有任务没执行完成,就先睡会吧
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- // 工作线程停止工作,且置为null
- for (int i = 0; i < worker_num; i++) {
- workThrads[i].stopWorker();
- workThrads[i] = null;
- }
- threadPool=null;
- taskQueue.clear();// 清空任务队列
- }
- // 返回工作线程的个数
- public int getWorkThreadNumber() {
- return worker_num;
- }
- // 返回已完成任务的个数,这里的已完成是只出了任务队列的任务个数,可能该任务并没有实际执行完成
- public int getFinishedTasknumber() {
- return finished_task;
- }
- // 返回任务队列的长度,即还没处理的任务个数
- public int getWaitTasknumber() {
- return taskQueue.size();
- }
- // 覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数
- @Override
- public String toString() {
- return "WorkThread number:" + worker_num + " finished task number:"
- + finished_task + " wait task number:" + getWaitTasknumber();
- }
- /**
- * 内部类,工作线程
- */
- private class WorkThread extends Thread {
- // 该工作线程是否有效,用于结束该工作线程
- private boolean isRunning = true;
- /*
- * 关键所在啊,如果任务队列不空,则取出任务执行,若任务队列空,则等待
- */
- @Override
- public void run() {
- Runnable r = null;
- while (isRunning) {// 注意,若线程无效则自然结束run方法,该线程就没用了
- synchronized (taskQueue) {
- while (isRunning && taskQueue.isEmpty()) {// 队列为空
- try {
- taskQueue.wait(20);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- if (!taskQueue.isEmpty())
- r = taskQueue.remove(0);// 取出任务
- }
- if (r != null) {
- r.run();// 执行任务
- }
- finished_task++;
- r = null;
- }
- }
- // 停止工作,让该线程自然执行完run方法,自然结束
- public void stopWorker() {
- isRunning = false;
- }
- }
- }
测试代码:
- package mine.util.thread;
- //测试线程池
- public class TestThreadPool {
- public static void main(String[] args) {
- // 创建3个线程的线程池
- ThreadPool t = ThreadPool.getThreadPool(3);
- t.execute(new Runnable[] { new Task(), new Task(), new Task() });
- t.execute(new Runnable[] { new Task(), new Task(), new Task() });
- System.out.println(t);
- t.destroy();// 所有线程都执行完成才destory
- System.out.println(t);
- }
- // 任务类
- static class Task implements Runnable {
- private static volatile int i = 1;
- @Override
- public void run() {// 执行任务
- System.out.println("任务 " + (i++) + " 完成");
- }
- }
- }
运行结果:
WorkThread number:3 finished task number:0 wait task number:6
任务 1 完成
任务 2 完成
任务 3 完成
任务 4 完成
任务 5 完成
任务 6 完成
WorkThread number:3 finished task number:6 wait task number:0
分析:由于并没有任务接口,传入的可以是自定义的任何任务,所以线程池并不能准确的判断该任务是否真正的已经完成(真正完成该任务是这个任务的run方法执行完毕),只能知道该任务已经出了任务队列,正在执行或者已经完成。
2、java类库中提供的线程池简介:
java提供的线程池更加强大,相信理解线程池的工作原理,看类库中的线程池就不会感到陌生了。
其他具体内容查看jdk帮助或看jdk源代码吧。。。
参考文章:http://hi.baidu.com/obullxl/blog/item/ee50ad1ba8e8ff1f8718bf66.html
相关推荐
线程池是一种多线程处理形式,通过预先创建一定数量的线程并管理它们,以提高系统的效率和响应性。在计算机科学中,特别是在软件开发领域,线程池是操作系统或者编程语言中的一种资源管理技术。它允许程序预先启动一...
corePoolSize:核心池的大小,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中; ...
阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池阻塞线程池...
一、要实现高效的线程池,可以考虑以下几点 二、实现线程池可以按照以下步骤进行 三、简单的C++线程池代码示例 四、 基于boost编写的源码库 - 线程池 4.1 基于boost编写的源码库地址 4.2 boost线程池的先进先出、...
### 线程池原理及创建(C++实现) #### 一、线程池的重要性 在现代计算环境中,网络服务器面临着处理大量并发请求的挑战,其中包括但不限于Web服务器、电子邮件服务器和数据库服务器。这类服务器通常需要在短时间...
java线程池使用后到底要关闭吗 java线程池是一种高效的并发编程技术,可以帮助开发者更好地管理线程资源,提高系统的性能和可靠性。然而,在使用java线程池时,一个常见的问题是:使用完线程池后到底要不要关闭?...
文章通过实例展示了如何创建一个全局线程池类,该类中封装了线程池对象,并提供了向线程池提交任务、检查任务是否在运行等方法。全局线程池的生命周期与Django主线程的生命周期一致,确保了线程资源的合理释放。 5....
线程池是多线程编程中的一个重要概念,它是一种线程使用模式,通过预先创建一组线程并维护一个线程集合来处理并发任务。在Windows操作系统中,内建的线程池API(Thread Pool API)提供了高效且灵活的线程管理机制,...
线程池是一种在多线程编程中非常重要的概念,它能有效地管理和调度系统中的线程资源,从而提高系统的效率和响应速度。在这个简单的线程池实现中,我们可以通过`pthread_pool.cpp`、`MainFunctionForTest.cpp`、`...
在编程领域,线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池在C++中是提高程序效率和资源管理的重要工具,尤其在处理大量并发操作时。本文将深入探讨VC++中...
Java8并行流中自定义线程池操作示例 Java8并行流中自定义线程池操作示例主要介绍了Java8并行流中自定义线程池操作,结合实例形式分析了并行流的相关概念、定义及自定义线程池的相关操作技巧。 1. 概览 Java8引入了...
Linux 线程池创建 C 实现 线程池是一种常用的并发编程技术,它可以提高应用程序的性能和响应速度。在 Linux 系统中,使用 C 语言创建线程池可以实现高效的并发处理。 什么时候需要创建线程池呢?简单的说,如果一...
DELPHI的线程池(ThreadPool)是一种高效管理并发任务的技术,它允许程序在需要时创建线程,而不是每次需要执行任务时都手动创建。线程池通过预先创建一组线程,然后根据需要分配任务,减少了线程创建和销毁的开销,...
本篇文章将重点探讨两种线程池实现:精易模块线程池和鱼刺模块线程池,并通过源码分析来展示它们的特点和用法。 首先,精易模块(SanYe Module)是由中国程序员SanYe开发的一系列开源模块,其中包含了线程池的实现...
在Linux系统中,线程池是一种高效的进程管理方式,它允许多个任务并行执行,同时限制了系统中并发线程的数量,以优化资源分配和调度。本项目实现了利用线程池进行目录拷贝的功能,这涉及到多个重要的编程概念和技术...
线程池是一种优化资源管理的机制,通过预先创建并维护一组可重用的线程,避免频繁地创建和销毁线程带来的性能开销。在Java、C++等编程语言中,线程池广泛应用于并发处理,提高系统效率,降低系统的资源消耗。本项目...
一、线程池 1、为什么需要使用线程池 1.1 创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率。 记创建线程消耗时间T1,执行任务消耗时间T2,销毁线程消耗时间T3,如果T1+T3>T2,那...
线程池管理和多线程上传是并发编程中的一个重要实践,特别是在大数据传输和网络服务中。在Java等编程语言中,线程池通过有效地管理和复用线程资源,避免了频繁创建和销毁线程带来的开销,提升了系统性能。下面将详细...
线程池是多线程编程中一个重要的概念,它能够优化系统资源的使用,提高系统的响应速度和效率。本篇文章将深入探讨C++中的线程池实现,并通过名为“OEasyPool-1.0”的示例来展示其工作原理。 线程池是预先创建并维护...
在C#编程中,线程池(ThreadPool)是一种高效的线程管理机制,它允许开发者创建并管理多个线程,而无需直接操作线程对象。线程池中的线程可以复用,减少了创建和销毁线程的开销。当我们需要执行大量短生命周期的任务...