多线程与 线程池

前段时间工作中遇到一个问题,需要开发一个工具 用来 把a数据库中的数据同步到b数据库。

代码是写出来了,跑一次问题还好,但是需要跑一段时间内的数据, 数据量大 ,对方提供的api限制等问题  ,就需要很长的时间的来同步这些数据。

那么怎么来做优化呢----多线程。

实现多线程 通用有2中的写法:继承 thread 类 和 实现runnable 接口 。

(1)继承thread类  

public class ExtendsThread extends Thread {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
    }
}

 

 (2)实现runnable接口

public class ImpleRunable implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub

    }

}

程序中有一串参数必须从 数据库中查询出来后再依次进行任务的执行。实现了多线程后发现一个问题,这些参数每一次请求都是不一样的,那么只好把这些参数全部拿出来,组装成多个任务,利用多线程实现.

 

 

下面贴出 据资料 编写的 线程池代码: 

 

package com.bfh.Thread.Pool;

import java.util.LinkedList;

import com.bfh.Thread.Task.Task;


/**
 * @desc 线程池
 * @author  bfh
 * @date 2015-09-27 14:31:51
 */
public class MyThreadPool extends ThreadGroup {

    private boolean isAlive;//线程池是否开启
    /** * 如果要支持多线程同步   直接在创建的时候 进行线程同步
     *    List list = Collections.synchronizedList(new LinkedList(...));*/
    private LinkedList taskQueue;//线程池的任务队列  
    private int threadID;//线程池中的线程Id
    private static int threadPoolID;//线程池ID
    
    /**
     * 创建新的线程池 numthreads 是线程池中的线程数
     * @param name
     */
    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();
        }
        
    }
    /**
     * 添加新任务
     * @throws IllegalAccessException 
     */
    public synchronized void performTask(Task task) throws IllegalAccessException{
        if (!this.isAlive) {
            throw new IllegalAccessException();//线程池被关闭  抛出异常
        }
        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 {
                /**
                 * join(long millis) 等待该线程终止的时间最长为 millis 毫秒
                     join(long millis, int nanos) 等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。
                     join()           等待该线程终止。
                 */
                threads[i].join();//等待线程运行结束
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
        
    }
    /**
     * 内部类  用于执行任务的工作线程
     * @author Administrator
     *
     */
    private class PooledThread extends Thread {
        
        //构造方法
        public PooledThread() {
            // TODO Auto-generated constructor stub
            //参数1 代表 该线程所在的线程组对象  即当前线程池对象
            //参数2 代表 线程名字
            super(MyThreadPool.this,"PooledThread-"+(threadID++));
        }
        
        @Override
        public void run() {
            //如果该线程没有被终止
            while(! isInterrupted()){
                //获取任务
                Task task = null;
                try {
                    task = getTask();
                } catch (InterruptedException e) {
                     
                }
                //只要线程池的任务列表不为空 getTask方法就总能得到一个任务
                //若getTask()返回null,就表示线程池中已经没有任务,而且线程池已被关闭
                if (task == null) {
                    return;
                }
                //运行任务  捕捉异常
                try {
                    task.preform();
                } catch ( Throwable t) { //此处个人理解  为  为了保持线程池 能执行完所有的任务 设置的异常处理机制
                    //当线程组中的线程有未被捕获的异常发生时
                    //jvm调用 uncaughtException 方法
                    uncaughtException(this, t);
                    /**
                     * api 解释如下
                     *  uncaughtException
                        void uncaughtException(Thread t,  Throwable e)
                     * 当给定线程因给定的未捕获异常而终止时,调用该方法。
                        Java 虚拟机将忽略该方法抛出的任何异常。
                     */
                }
            }
        }
    }

}
View Code
package com.bfh.Thread.Task;

public class MyTask implements Task {
    
    private int taskID = 0 ;//任务id
    

    public MyTask(int taskID) {
        this.taskID = taskID;
    }



    public MyTask() {
        super();
    }



    @Override
    public void preform() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("mytask    "+ taskID+ ":start");
        
        try {
//            StaticPath.
            Thread.sleep(1000);
        } catch (InterruptedException e) {
             System.out.println(e);
        }
        
        System.out.println("mytask    "+ taskID+ ":end");

    }

}
View Code
package com.bfh.Thread.Task;

/**
 * 任务接口类
 * @author Administrator
 *
 */
public interface Task {
    
    /**
     * 
     * @throws Exception
     */
    public void preform() throws Exception;

}
View Code
package com.bfh.Thread.Test;

import java.util.LinkedList;

/**
 * @desc   linkedlist remove(int index) 和 remove()
 * @author Administrator
 *
 */
public class TestLinkedListRemove {

    public static void main(String[] args) {
        
        int index = 2;
        
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("bfh1");
        linkedList.add("bfh2");
        linkedList.add("bfh3");
        
        if (index ==1) {
            linkedList.remove(0);
            for (String string : linkedList) {
                System.out.println(string);
            }
        }
        if (index == 2) {
            linkedList.removeFirst();
            for (String string : linkedList) {
                System.out.println(string);
            }
        }
        
    }
}
View Code
package com.bfh.Thread.PoolTest;

import com.bfh.Thread.Pool.MyThreadPool;
import com.bfh.Thread.Task.MyTask;

 

public class PoolTest {

    /**
     * @param args
     * @throws IllegalAccessException 
     */
    public static void main(String[] args) throws IllegalAccessException {
        // TODO Auto-generated method stub
        
        int numThreads = 3;//线程池中的线程数
        MyThreadPool myThreadPool = new MyThreadPool(numThreads);//生成线程池
        int numTasks = 10;//任务数
        
        //运行任务
        for (int i = 0; i < numTasks; i++) {
            myThreadPool.performTask(new MyTask(i));
        }
        //关闭线程池并等待所有任务完成
        myThreadPool.join();

    }

}

 

posted on 2015-11-16 23:11  盖世大将军  阅读(143)  评论(0)    收藏  举报

导航