• Java 线程池


     
    _____________________________________________________________________________

    ExecutorService——newScheduledThreadPool使用功能测试

    https://blog.csdn.net/wo541075754/article/details/51556198

    测试目的

    学习ScheduledExecutorService类创建的newScheduledThreadPool相关用法

    具体事例

    创建newScheduledThreadPool及scheduleAtFixedRate和scheduleWithFixedDelay方法的使用。

    package com.secbro.test.thread;
    
    import java.text.DateFormat;
    import java.util.Date;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。
     * @author zhuzhisheng
     * @Description
     * @date on 2016/6/1.
     */
    public class TestNewScheduledThreadPool {
    
        public static void main(String[] args) {
    
            ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
    
            scheduleAtFixedRate(service,1000);
            scheduleAtFixedRate(service,6000);
    
            scheduleWithFixedDelay(service,1000);
            scheduleWithFixedDelay(service,6000);
    
    
        }
    
        private static void scheduleAtFixedRate(ScheduledExecutorService service, final int sleepTime){
            service.scheduleAtFixedRate(new Runnable() {
                @Override
                public void run() {
                    long start = new Date().getTime();
                    System.out.println("scheduleAtFixedRate 开始执行时间:" +
                            DateFormat.getTimeInstance().format(new Date()));
                    try {
                        Thread.sleep(sleepTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    long end = new Date().getTime();
                    System.out.println("scheduleAtFixedRate 执行花费时间=" + (end -start)/1000 + "m");
                    System.out.println("scheduleAtFixedRate 执行完成时间:"
                            + DateFormat.getTimeInstance().format(new Date()));
                    System.out.println("======================================");
                }
            },1000,5000,TimeUnit.MILLISECONDS);
        }
    
        private static void scheduleWithFixedDelay(ScheduledExecutorService service,final int sleepTime){
            service.scheduleWithFixedDelay(new Runnable() {
                @Override
                public void run() {
                    long start = new Date().getTime();
                    System.out.println("scheduleWithFixedDelay 开始执行时间:" +
                            DateFormat.getTimeInstance().format(new Date()));
                    try {
                        Thread.sleep(sleepTime);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    long end = new Date().getTime();
                    System.out.println("scheduleWithFixedDelay执行花费时间=" + (end -start)/1000 + "m");
                    System.out.println("scheduleWithFixedDelay执行完成时间:"
                            + DateFormat.getTimeInstance().format(new Date()));
                    System.out.println("======================================");
                }
            },1000,5000,TimeUnit.MILLISECONDS);
        }
    }

    具体分析

    创建一个ScheduledExecutorService线程池的方法,以下为创建一个大小为2的线程池:

    ScheduledExecutorService service = Executors.newScheduledThreadPool(2);
    • 1

    scheduleAtFixedRate

    实验一

    scheduleAtFixedRate(service,1000);
    • 1

    输出结果为:

    scheduleAtFixedRate 开始执行时间:15:03:15
    scheduleAtFixedRate 执行花费时间=1m
    scheduleAtFixedRate 执行完成时间:15:03:16
    ======================================
    scheduleAtFixedRate 开始执行时间:15:03:20
    scheduleAtFixedRate 执行花费时间=1m
    scheduleAtFixedRate 执行完成时间:15:03:21
    ======================================

    分析得出:在任务执行时间小于间隔时间的情况下,程序以起始时间为准则,每隔指定时间执行一次,不受任务执行时间影响。

    实验二

    scheduleAtFixedRate(service,6000);
    • 1

    输出结果为:

    scheduleAtFixedRate 开始执行时间:15:06:12
    scheduleAtFixedRate 执行花费时间=6m
    scheduleAtFixedRate 执行完成时间:15:06:18
    ======================================
    scheduleAtFixedRate 开始执行时间:15:06:18
    scheduleAtFixedRate 执行花费时间=6m
    scheduleAtFixedRate 执行完成时间:15:06:24
    ======================================
    scheduleAtFixedRate 开始执行时间:15:06:24
    scheduleAtFixedRate 执行花费时间=6m
    scheduleAtFixedRate 执行完成时间:15:06:30

    分析得出:当执行任务时间大于间隔时间,此方法不会重新开启一个新的任务进行执行,而是等待原有任务执行完成,马上开启下一个任务进行执行。此时,执行间隔时间已经被打乱。

    scheduleWithFixedDelay

    实验一

    scheduleWithFixedDelay(service,1000);

    输出结果为:

    scheduleWithFixedDelay 开始执行时间:15:11:03
    scheduleWithFixedDelay执行花费时间=1m
    scheduleWithFixedDelay执行完成时间:15:11:04
    ======================================
    scheduleWithFixedDelay 开始执行时间:15:11:09
    scheduleWithFixedDelay执行花费时间=1m
    scheduleWithFixedDelay执行完成时间:15:11:10
    ======================================

    分析得出:当执行任务小于延迟时间时,第一个任务执行之后,延迟指定时间,然后开始执行第二个任务。

    实验二

    scheduleWithFixedDelay(service,6000);

    输出结果为:

    scheduleWithFixedDelay 开始执行时间:15:12:53
    scheduleWithFixedDelay执行花费时间=6m
    scheduleWithFixedDelay执行完成时间:15:12:59
    ======================================
    scheduleWithFixedDelay 开始执行时间:15:13:04
    scheduleWithFixedDelay执行花费时间=6m
    scheduleWithFixedDelay执行完成时间:15:13:10
    ======================================

    得出结论:当执行任务大于延迟时间时,第一个任务执行之后,延迟指定时间,然后开始执行第二个任务。

    总之:此方法无论任务执行时间长短,都是当第一个任务执行完成之后,延迟指定时间再开始执行第二个任务

     
    _____________________________________________________________________________

    Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor

     
    _____________________________________________________________________________
    java多线程之ForkJoinPool
    https://blog.csdn.net/tianshi_kco/article/details/53026192
    ForkJoinPool 分支/ 合并框架 工作窃取
    https://blog.csdn.net/zxm1306192988/article/details/59701101?utm_source=copy
     
    [JAVA学习笔记-53]ForkJoin_invoke_submit_execute区别
    https://blog.csdn.net/sinat_36263171/article/details/52837867
     
     
     
    _____________________________________________________________________________
     

    匿名内部类也就是没有名字的内部类,正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。

    但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

    1、继承一个父类的匿名内部类实现:

    abstract class People {
        public abstract void eat();
    }
     
    public class Demo {
        public static void main(String[] args) {
            People p = new People() {
                public void eat() {
                    System.out.println("I can eat ");
                }
            };
            p.eat();
        }
    }

    2、在接口上使用匿名内部类:

    interface People {
        public void eat();
    }
     
    public class Demo {
        public static void main(String[] args) {
            People p = new People() {           
                public void eat() {
                    System.out.println("I can eat ");
                }
            };
            p.eat();
        }
    }


    此处 new People( )看似实例化了一个接口,事实并非如此,接口式的匿名内部类是实现了一个接口的匿名类。而且只能实现一个接口。

    ps再来说一下线程创建的两种方式:

    (1)继承Thread类的方式因为耦合性太强,所以一般吧用。

    (2)常用实现Runnable接口的创建线程方式。

    但是我们更喜欢用匿名内部类的方式来创建一个线程。代码如下:

    new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				int i=0;
    				while(true){
    					i++;
    					System.out.println("this is 线程"+i);
    				}
    				
    				
    			}
    		}).start(); 

    就这一句话就可以创建并且启动一个线程,相对来说比较方便。而且特别直观易懂。

    此处的new Runnable( )并没有实例化了一个接口

  • 相关阅读:
    WCF开发笔记 高版本.Net的坑
    Net Start可以加载驱动
    解决:Windows 2008远程黑屏问题
    Visual Studio 解决方案版本从v12-->v14
    Visual Studio 使用之禁用/启用模板警告
    Windows 10 常用的快捷键及常用指令
    git
    Socket通信原理 很好
    java集合
    JavaEE简介
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/10819044.html
Copyright © 2020-2023  润新知