juc并发编程共享模式之工具threadpoolexecutor--任务调度线程池定时任务/延时执行(timer的缺点)(代码片段)

Z&&Y Z&&Y     2023-01-09     616

关键词:

1. 任务调度线程池


1.1 Timer的缺点

在『任务调度线程池』功能加入之前,可以使用 java.util.Timer 来实现定时功能,Timer 的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务。


1.1.1 正常情况

示例代码:

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;

@Slf4j(topic = "c.TestTimer")
public class TestTimer 
    public static void main(String[] args) throws ExecutionException, InterruptedException 
        Timer timer = new Timer();
        TimerTask task1 = new TimerTask() 
            @Override
            public void run() 
                log.debug("task 1");
            
        ;
        TimerTask task2 = new TimerTask() 
            @Override
            public void run() 
                log.debug("task 2");
            
        ;
        // 使用 timer 添加两个任务,希望它们都在 1s 后执行
        timer.schedule(task1, 1000);
        timer.schedule(task2, 1000);
    

运行结果:


1.1.2 让前面的任务睡眠(后面的任务被迫睡眠)

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;

@Slf4j(topic = "c.TestTimer")
public class TestTimer 
    public static void main(String[] args) throws ExecutionException, InterruptedException 
        Timer timer = new Timer();
        TimerTask task1 = new TimerTask() 
            @Override
            public void run() 
                try 
                    Thread.sleep(1500);
                 catch (InterruptedException e) 
                    e.printStackTrace();
                
                log.debug("task 1");
            
        ;
        TimerTask task2 = new TimerTask() 
            @Override
            public void run() 
                log.debug("task 2");
            
        ;
        // 使用 timer 添加两个任务,希望它们都在 1s 后执行
        timer.schedule(task1, 1000);
        timer.schedule(task2, 1000);
    

运行结果:

我们发现task2必须等到task1执行完毕后才会执行,这样就导致了task2也跟着睡眠了1.5秒


1.1.3 让前面的任务发生异常(后面任务不会执行)

package com.tian;

import lombok.extern.slf4j.Slf4j;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;

@Slf4j(topic = "c.TestTimer")
public class TestTimer 
    public static void main(String[] args) throws ExecutionException, InterruptedException 
        Timer timer = new Timer();
        TimerTask task1 = new TimerTask() 
            @Override
            public void run() 
            // 这里主动添加一个异常
                int number = 1 / 0;
                log.debug("task 1");
            
        ;
        TimerTask task2 = new TimerTask() 
            @Override
            public void run() 
                log.debug("task 2");
            
        ;
        // 使用 timer 添加两个任务,希望它们都在 1s 后执行
        timer.schedule(task1, 1000);
        timer.schedule(task2, 1000);
    

运行结果:



juc并发编程共享模式之工具jucreentrantlock--reentrantlock原理(代码片段)

1.ReentrantLock原理1.1非公平锁实现原理加锁解锁流程先从构造器开始看,默认为非公平锁实现:publicReentrantLock()sync=newNonfairSync();NonfairSync继承自AQS没有竞争时第一个竞争出现时:Thread-1执行了CAS尝试将state由0改为1,结果失... 查看详情

juc并发编程共享模式之工具juc线程安全的集合类--线程安全的集合类概述

...,线程安全的方法上面都是使用synchronized修饰,并发的性能比较低。时至今日不推荐使用。示例:1.2使用Collections装饰的线程安全集合在原来线程不安全的集合里面的方法多加了一个synchronized修饰,使得原来线程不安全... 查看详情

juc并发编程共享模式之工具threadpoolexecutor--线程池应用之定时任务(在每周周四执行定时任务)(代码片段)

1.线程池应用之定时任务示例:在每周周四执行定时任务packagecom.tian;importjava.time.DayOfWeek;importjava.time.Duration;importjava.time.LocalDateTime;importjava.util.concurrent.Executors;importjava.util.concurrent.ScheduledExec 查看详情

juc并发编程共享模式之工具jucsemaphore(信号量)--介绍&使用(代码片段)

1.Semaphore1.1介绍信号量,用来限制能同时访问共享资源的线程上限。作用类似于停车场里面的信号指示牌:显示还有多少空车位。1.2使用1.2.1不使用Semaphorepackagecom.tian;importlombok.extern.slf4j.Slf4j;@Slf4j(topic="c.TestSemaphore")... 查看详情

juc并发编程共享模式之工具jucsemaphore(信号量)--semaphore原理

1.Semaphore原理Semaphore有点像一个停车场,permits就好像停车位数量,当线程获得了permits就像是获得了停车位,然后停车场显示空余车位减一。刚开始permits(state)为3,这时5个线程来获取资源假设其中Thread-1&... 查看详情

juc并发编程共享模式之工具jucconcurrenthashmap--concurrenthashmap的错误使用和正确使用(示例:统计单词个数)(代码片段)

1.练习:单词计数1.1错误使用1.1.1生成测试数据packagecom.tian;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.OutputStreamWriter;importjava.io.PrintWriter;importjava.util.ArrayList;importjava.util 查看详情

juc并发编程共享模式之工具线程池--自定义线程池(阻塞队列)(代码片段)

...:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。解决思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免频繁创建销毁、实... 查看详情

juc并发编程共享模式之工具juc读写锁reentrantreadwritelock--reentrantreadwritelock(不可重入锁)使用&注意事项(代码片段)

...作远远高于写操作时,这时候使用读写锁让读-读可以并发,提高性能。类似于数据库中的select...from...lockinsharemode提供一个数据容器类内部分别使用读锁保护数据的read()方法,写锁保护数据的write()方法1.1示例代码:读-... 查看详情

juc并发编程共享模式之工具线程池jdk提供的线程池工具类--executors类创建线程池(创建threadpoolexecutor对象)(代码片段)

1.Executors类创建线程池ThreadPoolExecutor类构造方法:publicThreadPoolExecutor(intcorePoolSize, intmaximumPoolSize, longkeepAliveTime, TimeUnitunit, BlockingQueue<Runnable>workQueue, ThreadFactorythreadFacto 查看详情

juc并发编程共享模式之工具线程池jdk提供的线程池工具类--threadpoolexecutor(关闭线程池:shutdownshutdownnow)(代码片段)

1.关闭线程池1.1shutdown/*线程池状态变为SHUTDOWN-不会接收新任务-但已提交任务会执行完-此方法不会阻塞调用线程的执行*/voidshutdown();测试代码:packagecom.tian;importlombok.extern.slf4j.Slf4j;importjava.util.concurrent.ExecutionException;importjava.util 查看详情

juc并发编程共享模式之工具线程池jdk提供的线程池工具类--threadpoolexecutor(提交任务:submitexecuteinvokallinvokeany)(代码片段)

1.ThreadPoolExecutor提交任务//执行任务voidexecute(Runnablecommand);//提交任务task,用返回值Future获得任务执行结果<T>Future<T>submit(Callable<T>task);//提交tasks中所有任务<T>List<Future<T>>i 查看详情

juc并发编程共享模式之工具threadpoolexecutor--任务调度线程池定时任务/延时执行(scheduledthreadpoolexecutor延时执行/定时执行)(代(代码片段)

1.任务调度线程池1.1ScheduledThreadPoolExecutor延时执行示例代码(任务都延时1s执行):packagecom.tian;importjava.util.Date;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.Executors;importj 查看详情

juc并发编程共享模式之工具线程池jdk提供的线程池工具类--threadpoolexecutor(线程池状态构造方法)(代码片段)

1.ThreadPoolExecutor类图:1.1线程池状态ThreadPoolExecutor使用int的高3位来表示线程池状态,低29位表示线程数量从数字上比较,TERMINATED>TIDYING>STOP>SHUTDOWN>RUNNING(因为是高三位,所以第一位代表符号位(0正1负&#... 查看详情

juc并发编程共享模式之工具jucsemaphore(信号量)--限制对共享资源的使用改进数据库连接池(代码片段)

1.限制对共享资源的使用改进数据库连接池使用Semaphore限流,在访问高峰期时,让请求线程阻塞,高峰期过去再释放许可,当然它只适合限制单机线程数量,并且仅是限制线程数,而不是限制资源数。用Sema... 查看详情

juc并发编程共享模式之工具juccountdownlatch(倒计时锁)--countdownlatch(使用countdownlatch原理改进:配合线程池使用)(代码片段)

1.CountdownLatch用来进行线程同步协作,等待所有线程完成倒计时。其中构造参数用来初始化等待计数值,await()用来等待计数归零,countDown()用来让计数减一1.1使用示例代码:packagecom.tian;importlombok.extern.slf4j.Slf4j;importjava.ut... 查看详情

juc并发编程共享模式之工具threadpoolexecutor--任务调度线程池定时任务/延时执行(timer的缺点)(代码片段)

1.任务调度线程池1.1Timer的缺点在『任务调度线程池』功能加入之前,可以使用java.util.Timer来实现定时功能,Timer的优点在于简单易用,但由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,... 查看详情

juc并发编程共享模式之工具threadpoolexecutor多线程设计模式--异步模式之工作线程(定义饥饿&解决饥饿&线程池创建多少线程数目合适)(代码片段)

1.工作线程1.1定义让有限的工作线程(WorkerThread)来轮流异步处理无限多的任务。也可以将其归类为分工模式,它的典型实现就是线程池,也体现了经典设计模式中的享元模式例如:海底捞的服务员(线程)... 查看详情

juc并发编程共享模式之工具线程池--fork/join框架(jdk1.7新加入的线程池实现)(代码片段)

1.Fork/Join框架1.1介绍Fork/Join是JDK1.7加入的新的线程池实现,它体现的是一种分治思想,适用于能够进行任务拆分的cpu密集型运算所谓的任务拆分,是将一个大任务拆分为算法上相同的小任务,直至不能拆分可以直... 查看详情