我是一个“线程”

1、为什么要整多线程?

1)以你常用的Word为例,假设这个进程没有多线程(或者说它只有一个线程), 如果它有个定时保存文档的功能,你想象下,当这个自动保存的功能在运行的时候,就不能继续输入文字了。
2)单线程只能干一件事情,无法并发和并行。直接导致用户体验不好。CPU快速的运算能力,还有多核,就被浪费了。

2、为什么不整多进程,而是只整多线程?

1)进程是个重量级的家伙,并且进程之间是隔离的,他们要想共享数据,例如被编辑的文件内容,那是非常麻烦的。
2)实在是整不了,对操作系统来说,JVM其实就是java.exe运行起来,那它肯定是一个进程了。那在一个进程中还能进行多进程编程吗?

3、为什么要整线程池这个东西呢?

虽然线程是个轻量级的东西, 但是对于互联网应用来说,如果每个用户的请求都创建一个线程,那会非常得多,服务器也是难于承受, 再说了,众多的线程去竞争CPU,不断切换,也会让CPU调度不堪重负,很多线程将不得不等待。所以解决这个问题的基本思路就是:
(1)用少量的线程
(2) 让线程保持忙碌

就是说只创建一定数量的线程,放到线程池中,让这些线程去处理所有的任务,任务执行完了以后,线程并不结束,而是回到线程池中去,等待接受下一个任务。

4、线程池里的线程有时候有任务,有时候没任务,没任务的时候怎么整呢?

当线程池的线程刚创建时,让他们进入阻塞状态:等待某个任务的到来。 如果任务来了,那就好办,唤醒其中一个线程,让它拿到任务去执行即可。
BlockingQueue听说过没有? 就是一个线程调用它的take()方法取数据时, 如果这个Queue中没有数据,该线程会阻塞;同样,一个线程调用它的put方法放数据时,如果Queue满了, 也会阻塞。
这里写图片描述

5、线程池的代码实现?

线程池中每个线程的run()方法中,要设置一个循环,每次都尝试从BlockingQueue中获取任务,如果Queue是空的,就阻塞等待, 如果有任务来了,就会通知到线程池的某一个线程去处理,处理完了以后,依然试图从BlockingQueue中获取任务,就这么依次循环下去。

//线程池中的某个线程:
public class WorkerThread extends Thread {

    private BlockingQueue<Task> taskQueue = null;
    private boolean       isStopped = false;
    //持有一个BlockingQueue的实例
    public WorkerThread(BlockingQueue<Task> queue){
        taskQueue = queue;
    }

    public void run(){
        while(!isStopped()){
            try{
                Task task = taskQueue.take();
                task.execute();
            } catch(Exception e){
                //log or otherwise report exception,
                //but keep pool thread alive.
            }
        }
    }
    ......略......
}

后来Doug Lea大师写了一套非常好的实现,已经被吸收进JDK了,作为java.util.concurrent包的一部分,你直接调用即可,不用自己动手了。

ExecutorService executorService = Executors.newFixedThreadPool(10);

executorService.execute(new Runnable() {
    public void run() {
        System.out.println("Asynchronous task");
    }
});

executorService.shutdown();

猜你喜欢

转载自blog.csdn.net/gogletech/article/details/80332522