关于javataskqueue的信息

inEventLoop()方法有什么

线程模型啊

NioEventLoop相对NioEventLoopGroup来说就复杂很多了,需要一定的耐心来看这篇文章。

首先从NioEventLoop的启动讲起,对于线程池来说,启动一般都是从第一个任务的添加开始的。经过跟踪,找到execute()方法在SingleThreadEventExecutor类中:

[java] view plain copy

public void execute(Runnable task) {

if (task == null) {

throw new NullPointerException(“task”);

}

// inEventLoop表示启动线程与当前线程相同,相同表示已经启动,不同则有两种可能:未启动或者线程不同

boolean inEventLoop = inEventLoop();

if (inEventLoop) {

// 运行中则直接添加任务到队列中

addTask(task);

} else {

// 尝试启动任务

startExecution();

// 将任务加到任务队列taskQueue中

addTask(task);

// 发现已经关闭则移除任务并拒绝

if (isShutdown() removeTask(task)) {

reject();

}

}

if (!addTaskWakesUp wakesUpForTask(task)) {

// 唤醒执行线程

wakeup(inEventLoop);

}

}

private void startExecution() {

// 未启动的状态下才进行启动

if (STATE_UPDATER.get(this) == ST_NOT_STARTED) {

if (STATE_UPDATER.compareAndSet(this, ST_NOT_STARTED, ST_STARTED)) {

// 增加一个定时任务,该任务将定时任务队列中的已取消任务从队列中移除,该任务每间隔1秒执行1次

schedule(new ScheduledFutureTaskVoid(

this, Executors.Voidcallable(new PurgeTask(), null),

ScheduledFutureTask.deadlineNanos(SCHEDULE_PURGE_INTERVAL), -SCHEDULE_PURGE_INTERVAL));

// 开始执行

scheduleExecution();

}

}

}

// 如果已经关闭了,则不能再加任务,否则加入到任务队列中

protected void addTask(Runnable task) {

if (task == null) {

throw new NullPointerException(“task”);

}

if (isShutdown()) {

reject();

}

taskQueue.add(task);

}

关于javataskqueue的信息

java如何确定线程池最多线程的大小

new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds,runnableTaskQueue, handler);

参数:

corePoolSize(线程池的基本大小):当提交一个任务到线程池时,线程池会创建一个线程来执行任务,即使其他空闲的基本线程能够执行新任务也会创建线程,等到需要执行的任务数大于线程池基本大小时就不再创建。如果调用了线程池的prestartAllCoreThreads方法,线程池会提前创建并启动所有基本线程。

runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。 可以选择以下几个阻塞队列。

ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。

LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。

SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。

PriorityBlockingQueue:一个具有优先级的无限阻塞队列。

maximumPoolSize(线程池最大大小):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是如果使用了无界的任务队列这个参数就没什么效果。

ThreadFactory:用于设置创建线程的工厂,可以通过线程工厂给每个创建出来的线程设置更有意义的名字。

RejectedExecutionHandler(饱和策略):当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。以下是JDK1.5提供的四种策略。

AbortPolicy:直接抛出异常。

CallerRunsPolicy:只用调用者所在线程来运行任务。

DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。

DiscardPolicy:不处理,丢弃掉。

当然也可以根据应用场景需要来实现RejectedExecutionHandler接口自定义策略。如记录日志或持久化不能处理的任务。

keepAliveTime(线程活动保持时间):线程池的工作线程空闲后,保持存活的时间。所以如果任务很多,并且每个任务执行的时间比较短,可以调大这个时间,提高线程的利用率。

TimeUnit(线程活动保持时间的单位):可选的单位有天(DAYS),小时(HOURS),分钟(MINUTES),毫秒(MILLISECONDS),微秒(MICROSECONDS, 千分之一毫秒)和毫微秒(NANOSECONDS, 千分之一微秒)。

java的timer类如何判断程序超时呢?

参照如下的:

Timer类是用来执行任务的类,它接受一个TimerTask做参数

TimerTask是个抽象类,他扩展了Object并实现了Runnable接口,因此你必须在自己的Task中实现publicvoid run()方法。这也就是我们需要执行的具体任务。

Timer有两种执行任务的模式,最常用的是schedule,它可以以两种方式执行任务:1:在某个时间(Data),2:在某个固定的时间之后(intdelay).这两种方式都可以指定任务执行的频率

我们指定一个线程A,调用对象B.wait(timeout),线程A就会阻塞,直到timeout到了,B醒来会使A继续执行。

其实Timer类是为多任务定时设计的,在实现里面,B是一个任务队列(实现上就是一个array),维护着所有使用当前Timer定时的任务,它们可是一堆货真价实的线程实例。每次线程A都取队列中距离当前时间最近的的定时任务,跟当前时间比较,然后wait(timeout)这段时间。线程唤醒的时刻也是队列中这个定时任务运行的时刻。然后线程继续取下一个定时任务,继续wait(timeout)。从这里我们能看出来,每次定时都有额外的时间开销,比如要维护队列等,所以Java的Timer类不保证实时。

Timer中最主要由三个部分组成:

任务TimerTask 、 任务队列: TaskQueue queue 和 任务调试者:TimerThreadthread

Timer对任务的调度是基于绝对时间的。

所有的TimerTask只有一个线程TimerThread来执行,因此同一时刻只有一个TimerTask在执行。

任何一个TimerTask的执行异常都会导致Timer终止所有任务。

由于基于绝对时间并且是单线程执行,因此在多个任务调度时,长时间执行的任务被执行后有可能导致短时间任务快速在短时间内被执行多次或者干脆丢弃多个任务。

由于Timer/TimerTask有这些特点(缺陷),因此这就导致了需要一个更加完善的任务调度框架来解决这些问题。

默认情况下,只要一个程序的timer线程在运行,那么这个程序就会保持运行。当然,你可以通过以下四种方法终止一个timer线程:

调用timer的cancle方法。你可以从程序的任何地方调用此方法,甚至在一个timertask的run方法里。

让timer线程成为一个daemon线程(可以在创建timer时使用newTimer(true)达到这个目地),这样当程序只有daemon线程的时候,它就会自动终止运行。

当timer相关的所有task执行完毕以后,删除所有此timer对象的引用(置成null),这样timer线程也会终止。

调用System.exit方法,使整个程序(所有线程)终止。

什么是线程池

1、线程池简介:

多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。  

假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。

如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。

一个线程池包括以下四个基本组成部分:

1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;

2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;

3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;

4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。

线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。

线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目,看一个例子:

假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。

代码实现中并没有实现任务接口,而是把Runnable对象加入到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了

[java] view plaincopy

package mine.util.thread;

import java.util.LinkedList;

import java.util.List;

/**

* 线程池类,线程管理器:创建线程,执行任务,销毁线程,获取线程基本信息

*/

public final class ThreadPool {

// 线程池中默认线程的个数为5

private static int worker_num = 5;

// 工作线程

private WorkThread[] workThrads;

// 未处理的任务

private static volatile int finished_task = 0;

// 任务队列,作为一个缓冲,List线程不安全

private ListRunnable taskQueue = new LinkedListRunnable();

private static ThreadPool threadPool;

// 创建具有默认线程个数的线程池

private ThreadPool() {

this(5);

}

// 创建线程池,worker_num为线程池中工作线程的个数

private ThreadPool(int worker_num) {

ThreadPool.worker_num = worker_num;

workThrads = new WorkThread[worker_num];

for (int i = 0; i worker_num; i++) {

workThrads[i] = new WorkThread();

workThrads[i].start();// 开启线程池中的线程

}

}

// 单态模式,获得一个默认线程个数的线程池

public static ThreadPool getThreadPool() {

return getThreadPool(ThreadPool.worker_num);

}

// 单态模式,获得一个指定线程个数的线程池,worker_num(0)为线程池中工作线程的个数

// worker_num=0创建默认的工作线程个数

public static ThreadPool getThreadPool(int worker_num1) {

if (worker_num1 = 0)

worker_num1 = ThreadPool.worker_num;

if (threadPool == null)

threadPool = new ThreadPool(worker_num1);

return threadPool;

}

// 执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

public void execute(Runnable task) {

synchronized (taskQueue) {

taskQueue.add(task);

taskQueue.notify();

}

}

// 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

public void execute(Runnable[] task) {

synchronized (taskQueue) {

for (Runnable t : task)

taskQueue.add(t);

taskQueue.notify();

}

}

// 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定

public void execute(ListRunnable task) {

synchronized (taskQueue) {

for (Runnable t : task)

taskQueue.add(t);

taskQueue.notify();

}

}

// 销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁

public void destroy() {

while (!taskQueue.isEmpty()) {// 如果还有任务没执行完成,就先睡会吧

try {

Thread.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

// 工作线程停止工作,且置为null

for (int i = 0; i worker_num; i++) {

workThrads[i].stopWorker();

workThrads[i] = null;

}

threadPool=null;

taskQueue.clear();// 清空任务队列

}

// 返回工作线程的个数

public int getWorkThreadNumber() {

return worker_num;

}

// 返回已完成任务的个数,这里的已完成是只出了任务队列的任务个数,可能该任务并没有实际执行完成

public int getFinishedTasknumber() {

return finished_task;

}

// 返回任务队列的长度,即还没处理的任务个数

public int getWaitTasknumber() {

return taskQueue.size();

}

// 覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数

@Override

public String toString() {

return “WorkThread number:” + worker_num + ”  finished task number:”

+ finished_task + ”  wait task number:” + getWaitTasknumber();

}

/**

* 内部类,工作线程

*/

private class WorkThread extends Thread {

// 该工作线程是否有效,用于结束该工作线程

private boolean isRunning = true;

/*

* 关键所在啊,如果任务队列不空,则取出任务执行,若任务队列空,则等待

*/

@Override

public void run() {

Runnable r = null;

while (isRunning) {// 注意,若线程无效则自然结束run方法,该线程就没用了

synchronized (taskQueue) {

while (isRunning taskQueue.isEmpty()) {// 队列为空

try {

taskQueue.wait(20);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

if (!taskQueue.isEmpty())

r = taskQueue.remove(0);// 取出任务

}

if (r != null) {

r.run();// 执行任务

}

finished_task++;

r = null;

}

}

// 停止工作,让该线程自然执行完run方法,自然结束

public void stopWorker() {

isRunning = false;

}

}

}

测试代码:

[java] view plaincopy

package mine.util.thread;

//测试线程池

public class TestThreadPool {

public static void main(String[] args) {

// 创建3个线程的线程池

ThreadPool t = ThreadPool.getThreadPool(3);

t.execute(new Runnable[] { new Task(), new Task(), new Task() });

t.execute(new Runnable[] { new Task(), new Task(), new Task() });

System.out.println(t);

t.destroy();// 所有线程都执行完成才destory

System.out.println(t);

}

// 任务类

static class Task implements Runnable {

private static volatile int i = 1;

@Override

public void run() {// 执行任务

System.out.println(“任务 ” + (i++) + ” 完成”);

}

}

}

运行结果:

WorkThread number:3  finished task number:0  wait task number:6

任务 1 完成

任务 2 完成

任务 3 完成

任务 4 完成

任务 5 完成

任务 6 完成

WorkThread number:3  finished task number:6  wait task number:0

分析:由于并没有任务接口,传入的可以是自定义的任何任务,所以线程池并不能准确的判断该任务是否真正的已经完成(真正完成该任务是这个任务的run方法执行完毕),只能知道该任务已经出了任务队列,正在执行或者已经完成。

你好,本题已解答,如果满意

请点右下角“采纳答案”。

java 一个线程池可以有多个工作对列吗?如何实现

首先建立ThreadPool 的处理机制,即Thread可以由外部设置一个Runnable对象来运行,没有任务的时候,可以等待,建立一个任务队列(taskQueue),通过任务的名称或ID来区分不同的任务,可以指派每类任务采用不同的队列,如:

TaskQueue Extends Queue

{

object taskLock = null ;

Runnable Dequeue ()

{

synchronized (taskLock)

{

while (getCount () = 0)

{

taskLock.Wait () ;

}

return super.dequeue () ;

}

}

void Enqueue (Runnable runObject)

{

synchronized (taskLock)

{

super.enqueue (runObject) ;

taskLock.NotifyAll () ;

}

}

}

然后为不同的任务线程分配不同的队列。线程组赛在队列的DeQueue函数中,获取后即执行。

SingleThread Extends Thread

{

Runnable runObject ;

TaskQueue queue ;

public void run ()

{

while (true)

{

// if (runObject == null)

runObject = queue.Dequeue () ;

try{

runObject.run () ;}

}

}

}

ThreadPool接到新任务时,使用对应的Enqueue放入队列,并唤醒执行线程。

还需要补充一些任务配置,如:任务队列数量、名称等,是否要动态调整等等。

快速清理系统垃圾的运行指令是什么?

@echo off

echo 正在清除系统垃圾文件,请稍等……

del /f /s /q %systemdrive%\*.tmp

del /f /s /q %systemdrive%\*._mp

del /f /s /q %systemdrive%\*.log

del /f /s /q %systemdrive%\*.gid

del /f /s /q %systemdrive%\*.chk

del /f /s /q %systemdrive%\*.old

del /f /s /q %systemdrive%\recycled\*.*

del /f /s /q %windir%\*.bak

del /f /s /q %windir%\prefetch\*.*

rd /s /q %windir%\temp md %windir%\temp

del /f /q %userprofile%\cookies\*.*

del /f /q %userprofile%\recent\*.*

del /f /s /q “%userprofile%\Local Settings\Temporary Internet Files\*.*”

del /f /s /q “%userprofile%\Local Settings\Temp\*.*”

del /f /s /q “%userprofile%\recent\*.*”

echo 清除系统垃圾完成!

echo. pause

扩展资料:

在Windows操作系统安装和使用过程中都会产生相当多的垃圾文件,包括临时文件(如:*.tmp、*._mp)日志文件(*.log)、临时帮助文件(*.gid)、磁盘检查文件(*.chk)、临时备份文件(如:*.old、*.bak)以及其他临时文件。

特别是如果一段时间不清理IE的临时文件夹“Temporary Internet Files”,其中的缓存文件有时会占用上百MB的磁盘空间。这些LJ文件不仅仅浪费了宝贵的磁盘空间,严重时还会使系统运行慢如蜗牛。

参考资料来源:百度百科-清理系统垃圾

本文来自投稿,不代表【】观点,发布者:【

本文地址: ,如若转载,请注明出处!

举报投诉邮箱:253000106@qq.com

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2024年3月26日 14:41:34
下一篇 2024年3月26日 14:48:48

相关推荐

  • 关于avrstudio6c语言的信息

    c语言的程序员们你们公司用的开发工具是什么呢? 学c语言可以用的软件推荐如下:TurboC是由美国Borland公司开发的一套C语言程序开发工具,Borland公司是一家专门从事软件开发、研制的大公司。 Code:Blocks是一个开放源码的全功能的跨平台C/C++集成开发环境。Code:Blocks是开放源码软件。Code:Blocks由纯粹的C++语言开…

    2024年5月23日
    4500
  • 关于java如何查找线程的信息

    kill-3生成的线程堆栈怎么查看 通过给JVM发送一个SIGQUIT信号,您可以得到一个线程堆。 threaddump文件就是文本文件,可以使用任何文本查看工具进行查看; 建议使用比较高效的工具,比如more, less 等。 “Full thread dump”是一个全局唯一的关键字,你可以在中间件和单机版本Java的线程堆栈信息的输出日志中找到它(比如…

    2024年5月23日
    4000
  • 关于javasocketreader的信息

    用JAVA编写一个socket通信程序。 1、java编程对于Socket之间的通信过程如下:服务端往Socket的输出流里面写东西,客户端就可以通过Socket的输入流读取对应的内容。 2、服务端初始化ServerSocket,然后对指定的端口进行绑定,接着对端口及进行监听,通过调用accept方法阻塞。 此时,如果客户端有一个socket连接到服务端,那…

    2024年5月23日
    7900
  • 关于javapitfallspdf的信息

    怎么用java动态生成pdf文档 1、首先,您需要在 Java 程序中添加 Spire.Xls.jar 文件作为依赖项。您可以从这个链接下载 JAR 文件;如果您使用 Maven,则可以通过在 pom.xml 文件中添加以下代码导入 JAR 文件。 2、iText是着名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通…

    2024年5月23日
    4200
  • 关于pythonexcel打印设置字体的信息

    如何使用python更改excel表中的字体属性 字体,背景,边框等的颜色都可以通过三种方式设置:索引,aRGB或主题。 索引颜色是旧版实现,颜色本身取决于工作薄或应用程序默认提供的索引。主题颜色可用于互补色,但也取决于工作薄中存在的主题,因此,建议使用RGB颜色。 有着一定的参考价值,有需要的朋友可以参考一下可使用的第三方库python中处理excel表格…

    2024年5月23日
    4600
  • 关于linuxjpeg下载的信息

    请问怎么用grub2直接引导win10,本人Linux新手 第一步,当然是下载linux ubuntu1x的镜像了,这个小伙伴可以百度,去正规的网站现在,这里,我先提供一个站点:mirrors.xmu.edu.cn,厦门大学的信息与网络中心。里面有很多linux版本。有Deepin CenOS ubuntu什么什么的。 第一步:\x0d\x0a当然是下载Ub…

    2024年5月23日
    5200
  • 关于excel2013vc的信息

    如何利用VC++自动生成Excel表格 1、首先,我们需要点击文件菜单栏按钮。然后,我们点击生成EXE按钮。接下来,我们点击保存路径。然后,我们输入我们想要保存的文件名。最后,我们点击确定按钮。然后,我们便可以看到,在桌面生成了Excel表格了。 2、在主对话框中加入一个按钮 ID IDC_EXCELTEST Caption Test Excel 双击该按钮…

    2024年5月23日
    5200
  • 关于2t硬盘linux分区的信息

    linux硬盘2TB限制问题 1、Linux中进行磁盘分区一般是用fdisk这个命令,但是fdisk命令无法支持大于2TB以上的分区,而parted命令却是用于2TB以上大小的磁盘分区的工具。 2、asm无法识别2t磁盘是因为在分区的时候造成的,所以asm和linux都会有这个2T的限制。磁盘分区主要有MBR和GPT两种方式,发生2T限制的正是这个MBR方式…

    2024年5月23日
    8300
  • 关于linux下载geneontology的信息

    下载GO/KEGG某一pathway的genelist 功能(GO)或者通路(Pathway)富集分析时,都会涉及到 Background; 做分析时,分析工具会提供一些数据供使用者选择或者使用自定义的gene list。 clusterProfiler是一个功能强大的R包,同时支持GO和KEGG的富集分析,而且可视化功能非常的优秀,本章主要介绍利用这个R包…

    2024年5月23日
    5000
  • 关于linux下的mnt目录的信息

    Linux目录结构 总体而言,Linux系统的文件系统由块设备、分区、文件系统、目录结构、文件和元数据以及挂载点等组成。这种组织结构和层次关系提供了对文件和目录的有效管理和访问机制。 根目录和家目录均只是一种linux文件挂载点,linux采用树状发展目录结构根目录就是第一级,家目录与根目录看起来只是一个一级目录和二级目录的关系,实际上差别很大。 首先,打开…

    2024年5月23日
    5400

发表回复

登录后才能评论



关注微信