`
lc0451
  • 浏览: 47066 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
阅读更多

关键技术:

  • 线程组ThreadGroup可以管理多个线程,所以让线程池继承ThreadGroup。
  • 无条件关闭线程池时,通过ThreadGroup的interrupt方法中断池中所有线程。
  • 有条件关闭线程池时,通过ThreadGroup获得池中所有活动线程的引用,依次调用Thread的join方法等待活动线程执行完毕。当所有线程运行结束时,线程池才算被关闭。
  • 将任务放在LinkedList中,由于LinkedList不支持同步,所以在添加任务和获取任务的方法声明中必须使用synchronized关键字。

 


/**
 * 定义任务的接口类
 
*/
public   interface  Task {

    
/**
     * 执行任务
     * 
@throws  Exception 执行过程中可能出现的异常
     
*/
    
public   void  perform()  throws  Exception;
}

 


/**
 * 一个简单的任务
 
*/
public   class  MyTask  implements  Task{
    
/**     任务的ID     */
    
private   int  taskID  =   0 ;
    
    
public  MyTask( int  id){
        
this .taskID  =  id;
    }
    
/**
     * 实现Task接口的perform方法。
     
*/
    
public   void  perform()  throws  Exception{
        
        System.out.println(
" MyTask  "   +  taskID  +   " : start " );
        
//  休眠一秒
         try  {
            Thread.sleep(
1000 );
        }
        
catch  (InterruptedException ex) { 
        }
        System.out.println(
" MyTask  "   +  taskID  +   " : end " );
    }
}




import  java.util.LinkedList;

/**
 * 线程池,继承ThreadGroup。
 * ThreadGroup用于处理一组线程的类,它是一种树状结构,他的下层节点还可以是ThreadGroup对象
 
*/
public   class  MyThreadPool  extends  ThreadGroup {

    
/**     标志线程池是否开启     */
    
private   boolean  isAlive;
    
/**     线程池中的任务队列     */
    
private  LinkedList taskQueue;
    
/**     线程池中的线程ID     */
    
private   int  threadID;
    
/**     线程池ID     */
    
private   static   int  threadPoolID;

    
/**
     *  创建新的线程池,numThreads是池中的线程数
     
*/
    
public  MyThreadPool( int  numThreads) {
        
super ( " ThreadPool- "   +  (threadPoolID ++ ));
        
// 设置为该线程池是的daemon属性为true,
        
// 表示当该线程池中所有线程都被销毁时,该线程池会自动被销毁
         super .setDaemon( true );
        
this .isAlive  =   true ;
        
// 新建一个任务队列
         this .taskQueue  =   new  LinkedList();
        
// 启动numThreads个工作线程
         for  ( int  i  =   0 ; i  <  numThreads; i ++ ) {
            
new  PooledThread().start();
        }
    }
    
/**
     * 添加新任务
     
*/
    
public   synchronized   void  performTask(Task task) {
        
if  ( ! this .isAlive) {
            
//     线程被关则抛出IllegalStateException异常
             throw   new  IllegalStateException();
        }
        
if  (task  !=   null ) {
            
// 将任务放到任务队列的尾部
             this .taskQueue.add(task);
            
// 通知工作线程取任务
            notify();
        }

    }

    
/**
     * 获取任务
     
*/
    
protected   synchronized  Task getTask()  throws  InterruptedException {
        
// 如果任务列表为空,而且线程池没有被关闭,则继续等待任务
         while  ( this .taskQueue.size()  ==   0 ) {
            
if  ( ! this .isAlive) {
                
return   null ;
            }
            wait();
        }
        
// 取任务列表的第一个任务
         return  (Task)  this .taskQueue.removeFirst();
    }

    
/**
     * 关闭线程池,所有线程停止,不再执行任务
     
*/
    
public   synchronized   void  close() {
        
if  (isAlive) {
            
this .isAlive  =   false ;
            
// 清除任务
             this .taskQueue.clear();
            
// 中止线程池中所有线程
             this .interrupt();
        }
    }

    
/**
     * 关闭线程池,并等待线程池中的所有任务被运行完。
     * 但是不能接受新的任务。
     
*/
    
public   void  join() {
        
// 通知其他等待线程“该线程池已关闭”的消息
         synchronized  ( this ) {
            isAlive 
=   false ;
            notifyAll();
        }
        
//  等待所有线程完成
        
//  首先建立一个新的线程数组。activeCount方法获取线程池中活动线程的估计数
        Thread[] threads  =   new  Thread[ this .activeCount()];
        
//  将线程池中的活动线程拷贝到新创建的线程数组threads中。
         int  count  =   this .enumerate(threads);
        
for  ( int  i  =   0 ; i  <  count; i ++ ) {
            
try  {
                
//  等待线程运行结束
                threads[i].join();
            } 
catch  (InterruptedException ex) {
            }
        }
    }

    
/**
     * 内部类,用于执行任务的工作线程
     
*/
    
private   class  PooledThread  extends  Thread {

        
// 构造方法
         public  PooledThread() {
            
// 第一个参数为该线程所在的线程组对象,即当前线程池对象
            
// 第二个参数为线程名字
             super (MyThreadPool. this " PooledThread- "   +  (threadID ++ ));
        }

        
public   void  run() {
            
// 如果该线程没有被中止
             while  ( ! isInterrupted()) {

                
//  获取任务
                Task task  =   null ;
                
try  {
                    task 
=  getTask();
                } 
catch  (InterruptedException ex) {
                }

                
// 只要线程池的任务列表不为空,getTask方法总能得到一个任务。
                
// 若getTask()返回null,则表示线程池中已经没有任务,而且线程池已被关闭。
                 if  (task  ==   null ) {
                    
return ;
                }

                
//  运行任务,吸收异常
                 try  {
                    task.perform();
                } 
catch  (Throwable t) {
                    
// 当线程组中的线程有未被捕获的异常发生时,JVM就会去调用uncaughtException方法。
                    uncaughtException( this , t);
                }
            }
        }
    }
}

 

package  book.thread.pool;

/**
 * 测试线程池
*/
public   class  PoolTest {

    
public   static   void  main(String[] args) {

        
// 线程池中的线程数
         int  numThreads  =   3 ;
        
//  生成线程池
        MyThreadPool threadPool  =   new  MyThreadPool(numThreads);

        
//  任务数
         int  numTasks  =   10 ;
        
//  运行任务
         for  ( int  i = 0 ; i < numTasks; i ++ ) {
            threadPool.performTask(
new  MyTask(i));
        }

        
//  关闭线程池并等待所有任务完成
        threadPool.join();
    }
}

分享到:
评论

相关推荐

    Java多线程设计模式上传文件

    Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...

    java多线程读取文件

    Java多线程读大文件 java多线程写文件:多线程往队列中写入数据

    java多线程进度条

    java多线程进度条

    java多线程ppt

    java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题

    深入浅出 Java 多线程.pdf

    在本文中,我们将深入浅出Java多线程编程的世界,探索多线程编程的基本概念、多线程编程的优点、多线程编程的缺点、多线程编程的应用场景、多线程编程的实现方法等内容。 一、多线程编程的基本概念 多线程编程是指...

    java 多线程操作数据库

    一个java 多线程操作数据库应用程序!!!

    java多线程经典案例

    java多线程经典案例,线程同步、线程通信、线程阻塞等经典案例

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南(核心篇) 高清pdf带目录 随着现代处理器的生产工艺从提升处理器主频频率转向多核化,即在一块芯片上集成多个处理器内核(Core),多核处理器(Multicore Processor)离我们越来越近了――如今...

    Java多线程知识点总结

    该文档总结了Java多线程相关的知识点,分享给大家,简单易懂!

    java多线程的讲解和实战

    详细的讲解了java多线程的原理,并配有代码进行实战,适合java初学者和想对多线程有进一步了解的人。

    java多线程通信图解

    一张图方便理解和掌握java 多线程之间通信的实质 java 多线程 其实就是每个线程都拥有自己的内存空间,多线程之间的通信,比例A线程修改了主内存(main方法的线程)变量,需要把A线程修改的结果同步到主线程中,...

    java多线程处理数据库数据

    java多线程处理数据库数据,使用并发包,无框架,可批量处数据库数据,进行增删改。。等等操作。

    java多线程,对多线程,线程池进行封装,方便使用

    java多线程,对多线程,线程池进行封装,方便使用

    Java多线程编程经验

    现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。...本文档提供Java多线程编程经验,方便广大Java爱好者研究学习Java多线程

    java多线程处理大数据

    java多线程处理大数据,可根据配置的线程数,任务去调度处理

    java多线程并发

    java多线程并发的在新窗口

    Java多线程机制(讲述java里面与多线程有关的函数)

    Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...

    java多线程核心技术

    资深Java专家10年经验总结,全程案例式讲解,首本全面介绍Java多线程编程技术的专著 结合大量实例,全面讲解Java多线程编程中的并发访问、线程间通信、锁等最难突破的核心技术与应用实践 Java多线程无处不在,如...

    java多线程实现大批量数据导入源码

    java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制

    java多线程查询数据库

    java多线程并发查询数据库,使用线程池控制分页,并发查询。

Global site tag (gtag.js) - Google Analytics