Java线程池-ThreadPoolExecutor原理分析与实战
1. 为什么要用线程池
- 减少资源的开销
减少了每次创建线程、销毁线程的开销。 - 提高响应速度 ,每次请求到来时,由于线程的创建已经完成,故可以直接执行任务,因此提高了响应速度。
- 提高线程的可管理性 ,线程是一种稀缺资源,若不加以限制,不仅会占用大量资源,而且会影响系统的稳定性。 因此,线程池可以对线程的创建与停止、线程数量等等因素加以控制,使得线程在一种可控的范围内运行,不仅能保证系统稳定运行,而且方便性能调优。
2. Executor接口
由上可知,ThreadPoolExecutor是线程池的真正实现,通过构造方法的一系列参数,来构成不同配置的线程池
1) Executor两级调度模型
在HotSpot虚拟机中,Java中的线程将会被一一映射为操作系统的线程 在Java虚拟机层面,用户将多个任务提交给Executor框架,Executor负责分配线程执行它们; 在操作系统层面,操作系统再将这些线程分配给处理器执行
2) Executor结构
Executor框架中的所有类可以分成三类:
- 任务
任务有两种类型:Runnable和Callable。 - 任务执行器
Executor框架最核心的接口是Executor,它表示任务的执行器。
Executor的子接口为ExecutorService。
ExecutorService有两大实现类:ThreadPoolExecutor和ScheduledThreadPoolExecutor。 - 执行结果
Future接口表示异步的执行结果,它的实现类为FutureTask。
3) 四种类型的线程池
1. FixedThreadPool 定长线程池
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
- 它是一种固定大小的线程池;
- corePoolSize和maximunPoolSize都为用户设定的线程数量nThreads;
- keepAliveTime为0,意味着一旦有多余的空闲线程,就会被立即停止掉;但这里keepAliveTime无效;
- 阻塞队列采用了LinkedBlockingQueue,它是一个无界队列;
- 由于阻塞队列是一个无界队列,因此永远不可能拒绝任务;
- 由于采用了无界队列,实际线程数量将永远维持在nThreads,因此maximumPoolSize和keepAliveTime将无效。
2. CachedThreadPool 可缓存线程池
public static ExecutorService newCachedThreadPool(){return new ThreadPoolExecutor(0,Integer.MAX_VALUE,60L,TimeUnit.MILLISECONDS,new SynchronousQueue<Runnable>());
}
- 它是一个可以无限扩大的线程池;
- 它比较适合处理执行时间比较小的任务;
- corePoolSize为0,maximumPoolSize为无限大,意味着线程数量可以无限大;
- keepAliveTime为60S,意味着线程空闲时间超过60S就会被杀死;
- 采用SynchronousQueue装等待的任务,这个阻塞队列没有存储空间,这意味着只要有请求到来,就必须要找到一条工作线程处理他,如果当前没有空闲的线程,那么就会再创建一条新的线程。
3. SingleThreadExecutor 单一线程池
public static ExecutorService newSingleThreadExecutor(){return new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
}
- 它只会创建一条工作线程处理任务;
- 采用的阻塞队列为LinkedBlockingQueue;
4. ScheduledThreadPool 可调度的线程池
它用来处理延时任务或定时任务。
- 它接收SchduledFutureTask类型的任务,有两种提交任务的方式:
- scheduledAtFixedRate
- scheduledWithFixedDelay
- SchduledFutureTask接收的参数:
- time:任务开始的时间
- sequenceNumber:任务的序号
- period:任务执行的时间间隔
- 它采用DelayQueue存储等待的任务
- DelayQueue内部封装了一个PriorityQueue,它会根据time的先后时间排序,若time相同则根据sequenceNumber排序;
- DelayQueue也是一个无界队列;
- 工作线程的执行过程:
- 工作线程会从DelayQueue取已经到期的任务去执行;
- 执行结束后重新设置任务的到期时间,再次放回DelayQueue
3. 线程池的处理流程
一个线程从被提交(submit)到执行共经历以下流程:
- 线程池判断核心线程池里是的线程是否都在执行任务,如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则进入下一个流程
- 线程池判断工作队列是否已满。如果工作队列没有满,则将新提交的任务储存在这个工作队列里。如果工作队列满了,则进入下一个流程。
- 线程池判断其内部线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已满了,则交给饱和策略来处理这个任务。
线程池在执行execute方法时,主要有以下四种情况
- 如果当前运行的线程少于corePoolSize,则创建新线程来执行任务(需要获得全局锁)
- 如果运行的线程等于或多于corePoolSize ,则将任务加入BlockingQueue
- 如果无法将任务加入BlockingQueue(队列已满),则创建新的线程来处理任务(需要获得全局锁)
- 如果创建新线程将使当前运行的线程超出maxiumPoolSize,任务将被拒绝,并调用RejectedExecutionHandler.rejectedExecution()方法。
线程池采取上述的流程进行设计是为了减少获取全局锁的次数。在线程池完成预热(当前运行的线程数大于或等于corePoolSize)之后,几乎所有的excute方法调用都执行步骤2。
4. ThreeadPoolExecutor
1) ThreadPoolExecutor提供的构造函数
//五个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue)//六个参数的构造函数-1
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory)//六个参数的构造函数-2
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler)//七个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler)
2) 参数解释
- int corePoolSize:该线程池中核心线程数最大值
核心线程:线程池新建线程的时候,如果当前线程总数小于corePoolSize,则新建的是核心线程,如果超过corePoolSize,则新建的是非核心线程核心线程默认情况下会一直存活在线程池中,即使这个核心线程啥也不干(闲置状态)。
如果指定ThreadPoolExecutor的allowCoreThreadTimeOut这个属性为true,那么核心线程如果不干活(闲置状态)的话,超过一定时间(时长下面参数决定),就会被销毁掉。
- int maximumPoolSize: 该线程池中线程总数最大值
线程总数 = 核心线程数 + 非核心线程数。
- long keepAliveTime:该线程池中非核心线程闲置超时时长
一个非核心线程,如果不干活(闲置状态)的时长超过这个参数所设定的时长,就会被销毁掉,如果设置allowCoreThreadTimeOut = true,则会作用于核心线程。
- BlockingQueue workQueue:该线程池中的任务队列:维护着等待执行的Runnable对象
当所有的核心线程都在干活时,新添加的任务会被添加到这个队列中等待处理,如果队列满了,则新建非核心线程执行任务。
常用的workQueue类型:
- SynchronousQueue:这个队列接收到任务的时候,会直接提交给线程处理,而不保留它,如果所有线程都在工作怎么办?那就新建一个线程来处理这个任务!所以为了保证不出现<线程数达到了maximumPoolSize而不能新建线程>的错误,使用这个类型队列的时候,maximumPoolSize一般指定成Integer.MAX_VALUE,即无限大
- LinkedBlockingQueue:这个队列接收到任务的时候,如果当前线程数小于核心线程数,则新建线程(核心线程)处理任务;如果当前线程数等于核心线程数,则进入队列等待。由于这个队列没有最大值限制,即所有超过核心线程数的任务都将被添加到队列中,这也就导致了maximumPoolSize的设定失效,因为总线程数永远不会超过corePoolSize
- ArrayBlockingQueue:可以限定队列的长度,接收到任务的时候,如果没有达到corePoolSize的值,则新建线程(核心线程)执行任务,如果达到了,则入队等候,如果队列已满,则新建线程(非核心线程)执行任务,又如果总线程数到了maximumPoolSize,并且队列也满了,则发生错误
- DelayQueue:队列内元素必须实现Delayed接口,这就意味着你传进去的任务必须先实现Delayed接口。这个队列接收到任务时,首先先入队,只有达到了指定的延时时间,才会执行任务
- ThreadFactory threadFactory:创建线程的方式,这是一个接口,你new他的时候需要实现他的Thread newThread(Runnable r)方法,
- RejectedExecutionHandler handler: 当提交任务数超过maxmumPoolSize+workQueue之和时,任务会交给RejectedExecutionHandler来处理;jdk1.5提供了四种饱和策略 :
- AbortPolicy
默认。直接抛异常。 - CallerRunsPolicy
只用调用者所在的线程执行任务,重试添加当前的任务,它会自动重复调用execute()方法 - DiscardOldestPolicy
丢弃任务队列中最久的任务。 - DiscardPolicy
丢弃当前任务。
3) 提交任务
可以向ThreadPoolExecutor提交两种任务:Callable和Runnable。
- Callable
该类任务有返回结果,可以抛出异常。
通过submit函数提交,返回Future对象。
可通过get获取执行结果。 - Runnable
该类任务只执行,无法获取返回结果,并在执行过程中无法抛异常。
通过execute提交。
4) 关闭线程池
关闭线程池有两种方式:shutdown和shutdownNow,关闭时,会遍历所有的线程,调用它们的interrupt函数中断线程。但这两种方式对于正在执行的线程处理方式不同。
- shutdown()
仅停止阻塞队列中等待的线程,那些正在执行的线程就会让他们执行结束。 - shutdownNow()
不仅会停止阻塞队列中的线程,而且会停止正在执行的线程。
5) 设置合理的线程池大小
任务一般可分为:CPU密集型、IO密集型、混合型,对于不同类型的任务需要分配不同大小的线程池。
- CPU密集型任务
尽量使用较小的线程池,一般为CPU核心数+1。
因为CPU密集型任务使得CPU使用率很高,若开过多的线程数,只能增加上下文切换的次数,因此会带来额外的开销。 - IO密集型任务
可以使用稍大的线程池,一般为2*CPU核心数。
IO密集型任务CPU使用率并不高,因此可以让CPU在等待IO的时候去处理别的任务,充分利用CPU时间。 - 混合型任务
可以将任务分成IO密集型和CPU密集型任务,然后分别用不同的线程池去处理。
只要分完之后两个任务的执行时间相差不大,那么就会比串行执行来的高效。
因为如果划分之后两个任务执行时间相差甚远,那么先执行完的任务就要等后执行完的任务,最终的时间仍然取决于后执行完的任务,而且还要加上任务拆分与合并的开销,得不偿失。
5. ThreadPoolExecutor实战
1) 自主定制非阻塞线程池
package com.zach.concurrency.threadpool;import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;/*** @Author:Zach* @Description: 定制属于自己的非阻塞线程池* @Date:Created in 15:26 2018/8/14* @Modified By:*/
public class CustomThreadPoolExecutor {private ThreadPoolExecutor pool = null;/*** 线程池初始化方法** corePoolSize 核心线程池大小----10* maximumPoolSize 最大线程池大小----30* keepAliveTime 线程池中超过corePoolSize数目的空闲线程最大存活时间----30+单位TimeUnit* TimeUnit keepAliveTime时间单位----TimeUnit.MINUTES* workQueue 阻塞队列----new ArrayBlockingQueue<Runnable>(10)====10容量的阻塞队列* threadFactory 新建线程工厂----new CustomThreadFactory()====定制的线程工厂* rejectedExecutionHandler 当提交任务数超过maxmumPoolSize+workQueue之和时,* 即当提交第41个任务时(前面线程都没有执行完,此测试方法中用sleep(100)),* 任务会交给RejectedExecutionHandler来处理*/public void init() {pool = new ThreadPoolExecutor(10,30,30,TimeUnit.MINUTES,new ArrayBlockingQueue<Runnable>(10),new CustomThreadFactory(), new CustomRejectedExecutionHandler());}public void destory() {if(pool !=null) {pool.shutdownNow();}}public ExecutorService getCustomThreadPoolExecutor() {return this.pool;}private class CustomRejectedExecutionHandler implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {//记录异常System.out.println("error...................");}}private class CustomThreadFactory implements ThreadFactory {private AtomicInteger count = new AtomicInteger(0);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r);String threadName = CustomThreadPoolExecutor.class.getSimpleName()+count.addAndGet(1);System.out.println(threadName);t.setName(threadName);return t;}}public static void main(String[] args){CustomThreadPoolExecutor exec = new CustomThreadPoolExecutor();//1. 初始化exec.init();ExecutorService pool = exec.getCustomThreadPoolExecutor();for(int i=1;i<100;i++) {System.out.println("提交第"+i+"个任务");pool.execute(new Runnable() {@Overridepublic void run() {try {System.out.println(">>>task is running========");Thread.sleep(3000);}catch (InterruptedException e){e.printStackTrace();}}});}//2. 销毁----此处不能销毁,因为任务没有提交执行完,如果销毁线程池,任务也就无法执行//exec.destory();try {Thread.sleep(10000);}catch (InterruptedException e) {e.printStackTrace();}}/*** 方法中建立一个核心线程数为30个,缓冲队列有10个的线程池。每个线程任务,执行时会先睡眠3秒,保证提交10任务时,线程数目被占用完,再提交30任务时,阻塞队列被占用完,,这样提交第41个任务是,会交给CustomRejectedExecutionHandler 异常处理类来处理。提交任务的代码如下:/** Proceed in 3 steps:** 1. If fewer than corePoolSize threads are running, try to* start a new thread with the given command as its first* task. The call to addWorker atomically checks runState and* workerCount, and so prevents false alarms that would add* threads when it shouldn't, by returning false.** 2. If a task can be successfully queued, then we still need* to double-check whether we should have added a thread* (because existing ones died since last checking) or that* the pool shut down since entry into this method. So we* recheck state and if necessary roll back the enqueuing if* stopped, or start a new thread if there are none.** 3. If we cannot queue task, then we try to add a new* thread. If it fails, we know we are shut down or saturated* and so reject the task.*//**public void execute(Runnable command) {if (command == null)throw new NullPointerException();int c = ctl.get();if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);}else if (!addWorker(command, false))reject(command);}注意:41以后提交的任务就不能正常处理了,因为,execute中提交到任务队列是用的offer方法,如上面代码,这个方法是非阻塞的,所以就会交给CustomRejectedExecutionHandler 来处理,所以对于大数据量的任务来说,这种线程池,如果不设置队列长度会OOM,设置队列长度,会有任务得不到处理,接下来我们构建一个阻塞的自定义线程池*/
}
2) 自主定制阻塞线程池
package com.zach.concurrency.threadpool;import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;/*** @Author:Zach* @Description: 定制属于自己的阻塞线程池* @Date:Created in 15:26 2018/8/14* @Modified By:*/
public class CustomUnblockThreadPoolExecutor {private ThreadPoolExecutor pool = null;/*** 线程池初始化方法** corePoolSize 核心线程池大小----1* maximumPoolSize 最大线程池大小----3* keepAliveTime 线程池中超过corePoolSize数目的空闲线程最大存活时间----30+单位TimeUnit* TimeUnit keepAliveTime时间单位----TimeUnit.MINUTES* workQueue 阻塞队列----new ArrayBlockingQueue<Runnable>(5)==== 5容量的阻塞队列* threadFactory 新建线程工厂----new CustomThreadFactory()====定制的线程工厂* rejectedExecutionHandler 当提交任务数超过maxmumPoolSize+workQueue之和时,* 即当提交第9个任务时(前面线程都没有执行完,此测试方法中用sleep(100)),* 任务会交给RejectedExecutionHandler来处理*/public void init() {pool = new ThreadPoolExecutor(1,3,30,TimeUnit.MINUTES,new ArrayBlockingQueue<Runnable>(5),new CustomThreadFactory(), new CustomRejectedExecutionHandler());}public void destory() {if(pool !=null) {pool.shutdownNow();}}public ExecutorService getCustomThreadPoolExecutor() {return this.pool;}private class CustomRejectedExecutionHandler implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {//核心改造点,由blockingqueue的offer改成put阻塞方法try {executor.getQueue().put(r);} catch (InterruptedException e) {e.printStackTrace();}}}private class CustomThreadFactory implements ThreadFactory {private AtomicInteger count = new AtomicInteger(0);@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r);String threadName = CustomUnblockThreadPoolExecutor.class.getSimpleName()+count.addAndGet(1);System.out.println(threadName);t.setName(threadName);return t;}}public static void main(String[] args){CustomUnblockThreadPoolExecutor exec = new CustomUnblockThreadPoolExecutor();//1. 初始化exec.init();ExecutorService pool = exec.getCustomThreadPoolExecutor();for(int i=1;i<100;i++) {System.out.println("提交第"+i+"个任务");pool.execute(new Runnable() {@Overridepublic void run() {try {System.out.println(">>>task is running========");TimeUnit.SECONDS.sleep(10);}catch (InterruptedException e){e.printStackTrace();}}});}//2. 销毁----此处不能销毁,因为任务没有提交执行完,如果销毁线程池,任务也就无法执行//exec.destory();try {Thread.sleep(10000);}catch (InterruptedException e) {e.printStackTrace();}}/*** 解释:当提交任务被拒绝时,进入拒绝机制,我们实现拒绝方法,把任务重新用阻塞提交方法put提交,实现阻塞提交任务功能,防止队列过大,OOM,提交被拒绝方法在下面** public void execute(Runnable command) {if (command == null)throw new NullPointerException();int c = ctl.get();if (workerCountOf(c) < corePoolSize) {if (addWorker(command, true))return;c = ctl.get();}if (isRunning(c) && workQueue.offer(command)) {int recheck = ctl.get();if (! isRunning(recheck) && remove(command))reject(command);else if (workerCountOf(recheck) == 0)addWorker(null, false);}else if (!addWorker(command, false))// 进入拒绝机制, 我们把runnable任务拿出来,重新用阻塞操作put,来实现提交阻塞功能reject(command);}*/
}
总结:
1、用ThreadPoolExecutor自定义线程池,看线程是的用途,如果任务量不大,可以用无界队列,如果任务量非常大,要用有界队列,防止OOM
2、如果任务量很大,还要求每个任务都处理成功,要对提交的任务进行阻塞提交,重写拒绝机制,改为阻塞提交。保证不抛弃一个任务
3、最大线程数一般设为2N+1最好,N是CPU核数
4、核心线程数,看应用,如果是任务,一天跑一次,设置为0,合适,因为跑完就停掉了,如果是常用线程池,看任务量,是保留一个核心还是几个核心线程数
5、如果要获取任务执行结果,用CompletionService,但是注意,获取任务的结果的要重新开一个线程获取,如果在主线程获取,就要等任务都提交后才获取,就会阻塞大量任务结果,队列过大OOM,所以最好异步开个线程获取结果
6. 参考资料
ThreadPoolExecutor使用详解
深入浅出Java线程池
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- java架构师第二期项目实战(完整)
001_互联网架构视频第二期(1-4)002_互联网架构视频第二期(005)003_互联网架构视频第二期(006)004_互联网架构视频第二期(007)005_互联网架构视频第二期(008)006_互联网架构视频第二期(009)007_互联网架构视频第二期(010)008-互联网架构视频第二期(011)009_互联网架构视频第二期…...
2024/4/21 9:55:25 - SAP_ABAP_ABAP中如何使用NATIVE SQL及其弊端
可以用EXEC SQL来执行NATIVE SQL。 NATIVE SQL在使用时需要注意指定CLIENT,如果没有指定,会将系统中所有CLIENT的数据都取出来; NATIVE SQL在ABAP中不能进行语法检查和调试。...
2024/4/21 9:55:24 - Java NIO实战之聊天室
在工作之余花了两个星期看完了《Java NIO》,总体来说这本书把NIO写的很详细,没有过多的废话,讲的都是重点,只是翻译的中文版看的确实吃力,英文水平太低也没办法,总算也坚持看完了。《Java NIO》这本书的重点在于第四章讲解的“选择器”,要理解透还是要反复琢磨推敲;愚钝…...
2024/4/21 9:55:22 - Linux下使用Wireshark进行抓包分析(含SIP和RTP包)
遇到需要在Linux下抓包分析的问题,便用到了wireshark,非常强大的抓包分析软件,直接在系统里面安装,然后使用明亮抓包即可!我这里用的是Ubuntu server版,执行安装: apt-get install wireshark安装成功后使用命令进行抓包: tshark -i eth0 port 6060 抓制定网卡和端口的包…...
2024/4/22 23:49:13 - Java项目总结
Java就是用来做项目的! Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点:1、掌握项目开发的基本步骤2、具备极强的面向对象的分析与设计技巧3、掌握用例驱动、以架构为核心的主流开发方法没有人愿意自己一辈子就满足于掌握了一些代码…...
2024/4/23 4:54:15 - abap代码获取采购订单po中的抬头文本
如下图所示,事务码ME23N查看一张具体的采购订单的内容:在采购订单PO的抬头部分,有一个tab名为【文本】,这里面如图所示的抬头文本,里面的内容,我们要写abap代码提取出来,然后在alv中显示出来。去哪里找?我们双击右侧那个大框,如下所示点击转到、表头如何提取上述内容,…...
2024/4/21 9:55:19 - 使用wireshark分析mqtt数据
一开始直接过滤没有发现mqtt的协议(后来发现是开始捕获数据的时候,1883端口刚好没有数据),上网看了要加.lua脚本,加了不好用。有的博客说最新的wireshark不需要脚本,于是直接升级到了Version 3.2.2 (v3.2.2-0-ga3efece3d640)。由于端口问题和测试时间问题还是没有数据。看…...
2024/4/22 11:47:37 - SSM整合进阶项目实战-个人博客系统-钟林森-专题视频课程
SSM整合进阶项目实战-个人博客系统—398人已学习 课程介绍 "SSM整合进阶项目实战-个人博客系统开发",属于中级课程,适合于具备了一定java基础以及Spring,SpringMVC跟Mybatis核心框架的基础要点。本课程将更深入的基于SSM整合更多的第三方框架并实现一套比较…...
2024/4/30 2:35:18 - 类CL_ABAP_TYPEDESCR,动态取得运行时类型
有时候我们要在程序运行的时候取得某个内表或者某个结构它的属性或者它的字段的属性,可能通过类CL_ABAP_TYPEDESCR和它的子类取得指定内表的属性。类CL_ABAP_TYPEDESCR和它的子类的结构图CL_ABAP_TYPEDESCR | |--CL_ABAP_DATADESCR | | | |--CL_ABAP_ELEMDESCR | …...
2024/4/25 10:54:06 - ABAP 调用java 程序
ABAP调用外部java程序, 网上搜到, 转贴备查.未测试.原文地址: http://zhidao.baidu.com/question/48890437.html---------------以下是转贴内容-------------------------------------------REPORT zexecute.*实例 abap调用java文件DATA para TYPE string.PARAMETER mytext TY…...
2024/4/21 9:55:15 - [笔记][Java7并发编程实战手册]系列目录
推荐学习多线程之前要看的书。 [笔记][思维导图]读深入理解JAVA内存模型整理的思维导图文章里面的思维导图或则对应的书籍。去看一遍。能理解为什么并发编程就会出现问题。Java7并发编程实战手册 这一本实战的书籍。本笔记记录是看了该书。随笔的一些笔记,和在实际动手敲示例的…...
2024/4/20 17:58:52 - ABAP 生成唯一标识GUID
ABAP开发中经常需要为某字段(通常是主键或索引)自动生成唯一标识,可以通过GUID实现备注GUID全局唯一标识符(Globally Unique Identifier)是UUID(Universally Unique Identifier)的一种实现ABAP使用方法1、函数GUID_CREATE(已过时,不推荐)2、标准类cl_system_uuid,提供…...
2024/4/23 8:40:55 - 【Java实战】Java实现简易音乐播放器
作者博客地址:http://www.yooongchun.cn/ 摘要:本文使用java基础技术实现了一个可播放mid、wav格式音乐的简易音乐播放器,带UI //此程序实现mid.wav格式音频文件的播放//暂时只实现了单曲播放功能<播放面板里的play//选项>其它功能会后继添加//Version 1.0 // @author…...
2024/4/20 10:42:15 - ABAP工作台(一)
ABAP工作台包含SAP应用开发所用到的所有工具。以后将陆续分享各个工具的用法。(一)对象浏览器(SE80)对象浏览器是一个集成的开发环境,它可以调用SAP应用开发的其它工具。导航列表区包括:对象类型列表,对象类型下拉框,对象名称输入框,程序对象列表。开发工具区包括:主…...
2024/4/20 17:58:49 - JAVA中利用不规则二维数组输出杨辉三角形
1. 不规则二维数组 Java中创建高维数组时,分配内存空间有以下几种方法(此处以二维数组为例): (1)直接为每一维分配空间 int a[][] = new int [2][3] 或a = new int [2][3](2)从最高维开始,分别为每一维分配空间 int a[][] = new int [2][]; //指定第一维维数 a[0] =…...
2024/4/21 9:55:15 - ABAP上传文件到服务器
ABAP如何实现上传本地文件到FTP服务器 想通过ABAP程序上传本地文件到FTP服务器?原以为通过FTP_CONNECT,FTP_COMMAND等FM可以实 现,试了好像不行,只能实现将文件从应用服务器传输到FTP服务器上,有哪位高手知道方法? 用FTP_CONNECT,FTP_COMMAND就可以实现了http://hi.baid…...
2024/4/21 9:55:13 - 转载 强大! 用WIN PE通过修改系统注册表修复因盘符错乱而导致系统无法启动问题 ...
[color=red]症状:[/color]XP系统启动时,画面停留在欢迎界面,但是没有出现选择用户和输入用户名和密码的输入框.一直停留在那个界面,按键盘数字开启数字键数字键盘指示灯会有反应,所以应该不是死机状.[color=red]病因:[/color]本人这台是台式机,挂有两个SATA硬盘,和一个PATA光驱…...
2024/4/25 17:15:20 - ABAP屏幕上显示LIST的三种方法
屏幕上显示LIST的三种方法在abap开发中,经常有用户提出list的需求,实现的方法很多,通常用的有以下三种总结一下供大家参考:1:手工添加-就是根据需要把LIST要显示的内容一条一条加到LIST列表中。对于手工添加,其优点就是简单,对列表数据少且固定的LIST较易实现,缺点就是…...
2024/4/21 9:55:11 - wireshark抓包过滤指定的字节数据
在使用wireshark抓包的时候,文本信息还好,但是遇到二进制的信息时,就需要对指定的字节信息进行过滤来找到你想要找的包了 tcp[20:4]==30:30:30:30 代表的意思是,TCP数据报文中,出掉头部的20字节,之后的4个字节的数据为`30:30:30:30`...
2024/4/21 9:55:10 - 使用Java在本地创建一个服务器 ,通过浏览器对其进行访问的一个简单测试
上代码/** 在本地创建一个服务器 通过浏览器对其进行访问的一个简单测试 */ import java.net.*; import java.io.*; public class Server {public static void main(String[] args)throws Exception{ServerSocket ss=new ServerSocket(9999);Socket sk=ss.accept();PrintWriter…...
2024/4/21 9:55:09
最新文章
- 华纳云:服务器DDoS攻击有哪些类型?
DDoS(分布式拒绝服务)攻击是一种网络攻击,旨在通过向目标服务器发送大量恶意流量,以消耗其资源或使其网络不可用。DDoS 攻击可以分为多种类型,主要根据攻击的方式和目标进行分类。以下是几种常见的 DDoS 攻击类型: UDP Flood 攻击…...
2024/5/1 5:45:07 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - 使用Nginx搭载文件服务器
1.进入nginx.conf的配置 带有alias别名的配置 location /root {alias /home/icore;autoindex on; } 带有别名:alias的路径 当访问ip:port/root 默认会直接进入到/home/icore , 浏览器显示的是/home/icore目录下的内容, 不带alias别名使用root的配置 …...
2024/4/19 3:32:38 - AI小程序的创业方向:深度思考与逻辑引领
随着人工智能技术的快速发展,AI小程序逐渐成为创业的新热点。在这个充满机遇与挑战的时代,我们有必要深入探讨AI小程序的创业方向,以把握未来的发展趋势。 一、目标市场定位 首先,我们要明确目标市场。针对不同的用户需求&#x…...
2024/4/30 2:38:07 - 理解 Golang 变量在内存分配中的规则
为什么有些变量在堆中分配、有些却在栈中分配? 我们先看来栈和堆的特点: 简单总结就是: 栈:函数局部变量,小数据 堆:大的局部变量,函数内部产生逃逸的变量,动态分配的数据&#x…...
2024/4/30 2:57:27 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/4/29 23:16:47 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/4/30 18:14:14 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/29 2:29:43 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/4/30 18:21:48 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/27 17:58:04 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/27 14:22:49 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/28 1:28:33 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/30 9:43:09 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/27 17:59:30 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/4/25 18:39:16 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/28 1:34:08 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/26 19:03:37 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/29 20:46:55 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/30 22:21:04 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/1 4:32:01 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/27 23:24:42 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/28 5:48:52 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/30 9:42:22 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/4/30 9:43:22 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/30 9:42:49 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57