java的多线程学习,第四记

假如写网络编程的程序,socket编程就是响应客户编程的服务端。

public class ThreadPool {

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(80);
        while (true){
            Socket socket = serverSocket.accept();
            Runnable task = new Runnable() {
                @Override
                public void run() {
                    handleRequest(socket);
                }
            };
            new Thread(task).start();
        }
    }

    private static void handleRequest(Socket socket) {

    }
}

这样做,每来一个就创建一个线程,会出现很多问题的。java虚拟机就挂掉了,内存溢出。

资源消耗得不到限制,并不能控制线程的数量。

//Executor 线程池
创建线程池
Executor executor = Executors.newFixedThreadPool(100);

拥有100线程的线程池。

Executor executor1 = Executors.newSingleThreadExecutor();

池子里,永远只有一个线程。平常如果new一个线程,挂掉了就没有了。

single这个如果被占用了,就阻塞这里等着,如果有异常了,就拿一条新的线程。

Executor executor2 = Executors.newCachedThreadPool();

这个是缓冲线程池,不知道有多少个线程。来一个创建一个,来一个创建一个。没有上限的。

Executor是个接口,ExecutorService是个子类。

线程池的任务丢进去是不可控的,什么时间关闭,如果executor没有运行完,jvm是不可能关闭的,除非你强行关闭电源。

ExecutorService提供了关闭的方法。

List<Runnable> shutdownNow();
void shutdown();
boolean isTerminated();

线程池有三种状态:

1,运行状态。running

2,关闭状态。shutdown状态,不是立即终止,停止接受新的任务,但是等待提交的任务完成。

3,终止状态。什么任务都完成了。把线程池掐掉。

shutdownNow返回还没有执行完的任务的线程。isTerminated是所有线程都死掉了。

tomcat源码用的exector,解析http协议。

public class ThreadPool {

    static ExecutorService executor = Executors.newFixedThreadPool(100);

    //Executor 线程池
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(80);
        while (!executor.isShutdown()){
            Socket socket = serverSocket.accept();
            try {
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        handleRequest(socket);
                    }
                });
                //RejectedExecutionException 拒绝执行任务异常
            } catch (RejectedExecutionException e) {
                if (!executor.isShutdown()){
                    System.out.println("线程池接受任务被拒绝");
                    throw e;
                }
            }
        }
    }

    public void stop(){
        executor.shutdown();
    }

    private static void handleRequest(Socket socket) {

    }
}
Executors.newScheduledThreadPool();

java的定时任务的执行,可调度的定时任务的执行。

public class Shedule {

    private static long start;

    private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);

    public static void main(String[] args) {
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis()-start);
                try{
                    Thread.sleep(3000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        };
        TimerTask task1 = new TimerTask(){
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis()-start);
            }
        };

        Timer timer = new Timer();
        start = System.currentTimeMillis();
        //启动一个调度任务,delay延迟毫毛单位
        timer.schedule(task,1000);
        timer.schedule(task1,3000);
    }

}

 用Timer,线程之间是相互干扰的。Timer是个单线程。

public class Shedule {

    private static long start;

    private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);

    public static void main(String[] args) {
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis()-start);
                try{
                    Thread.sleep(3000);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        };
        TimerTask task1 = new TimerTask(){
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis()-start);
            }
        };

//        Timer timer = new Timer();
        start = System.currentTimeMillis();
        //启动一个调度任务,delay延迟毫毛单位
//        timer.schedule(task,1000);
//        timer.schedule(task1,3000);
        executorService.schedule(task,1000, TimeUnit.MILLISECONDS);
        executorService.schedule(task,3000, TimeUnit.MILLISECONDS);
    }

}

如果第一个线程异常了,那么就阻塞在这了。

public class Shedule {

    private static long start;

    private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);

    public static void main(String[] args) {
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                throw new RuntimeException();
            }
        };
        TimerTask task1 = new TimerTask(){
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis()-start);
            }
        };

        Timer timer = new Timer();
        start = System.currentTimeMillis();
        //启动一个调度任务,delay延迟毫毛单位
        timer.schedule(task,1000);
        timer.schedule(task1,3000);
//        executorService.schedule(task,1000, TimeUnit.MILLISECONDS);
//        executorService.schedule(task,3000, TimeUnit.MILLISECONDS);
    }

}

executorService用的是相对时间,不是系统时间。

用那些pool,实际上底层返回的是ThreadPoolExecutor返回的。

 public ThreadPoolExecutor(int corePoolSize,//线程数量
                              int maximumPoolSize,//最大的线程数量
                              long keepAliveTime,//线程活跃的时间是多少
                              TimeUnit unit,//时间单位
                              BlockingQueue<Runnable> workQueue//里面装的是Runnable 并发容器 workQueue工作队列) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

executor接口,关闭不是很好关闭。

Executors是工具类,可以搞线程池这些东西。这里面的方法最终弄的是ThreadPoolExecutor。都可以指定的。


原文地址:https://www.cnblogs.com/fuckingPangzi/p/10155315.html