• 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。都可以指定的。

    
    
  • 相关阅读:
    WPF Video Tutorials
    英语词汇看病
    回车键的含义
    勘误《新概念》IV
    2010年春季C语言程序设计答疑时间地点安排
    勘误《新概念》III
    A potentially dangerous Request.Form value was detected from the client
    推荐WPF的好书(图书)
    *英语词汇交通
    英语词汇房地产
  • 原文地址:https://www.cnblogs.com/fuckingPangzi/p/10155315.html
Copyright © 2020-2023  润新知