当前位置:首页 » 编程语言 » java任务队列

java任务队列

发布时间: 2022-06-11 03:22:33

‘壹’ java任务队列用缓存还是数据库表实现较好

不能简单说谁好谁坏,各有适用场景。
数据库在持久化方面比较好,服务宕机,数据还在,但并发性能方面不如缓存。
如果用缓存,最主要是要处理好多线程时线程安全、宕机缓存丢失的问题。如果是分布式部署,同步缓存也要考虑。

‘贰’ Java中关于如何实现多线程消息队列的实例

java中的消息队列
消息队列是线程间通讯的手段:

import java.util.*

public class MsgQueue{

private Vector queue = null;
public MsgQueue(){
queue = new Vector();
}
public synchronized void send(Object o)
{
queue.addElement(o);
}
public synchronized Object recv()
{
if(queue.size()==0)
return null;
Object o = queue.firstElement();
queue.removeElementAt(0);//or queue[0] = null can also work
return o;
}
}

因为java中是locked by object的所以添加synchronized 就可以用于线程同步锁定对象
可以作为多线程处理多任务的存放task的队列。他的client包括封装好的task类以及thread类

Java的多线程-线程间的通信2009-08-25 21:58
1. 线程的几种状态
线程有四种状态,任何一个线程肯定处于这四种状态中的一种:
1) 产生(New):线程对象已经产生,但尚未被启动,所以无法执行。如通过new产生了一个线程对象后没对它调用start()函数之前。
2) 可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。当一个线程处于可执行状态时,表示它可能正处于线程池中等待排排程器启动它;也可能它已正在执行。如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一定正在执行中。
3) 死亡(Dead):当一个线程正常结束,它便处于死亡状态。如一个线程的run()函数执行完毕后线程就进入死亡状态。
4) 停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。当处于停滞状态的线程重新回到可执行状态时,它有可能重新执行。如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状态。
2. classThread下的常用函数函数
2.1 suspend()、resume()
1) 通过suspend()函数,可使线程进入停滞状态。通过suspend()使线程进入停滞状态后,除非收到resume()消息,否则该线程不会变回可执行状态。
2) 当调用suspend()函数后,线程不会释放它的“锁标志”。
例11:
class TestThreadMethod extends Thread{
public static int shareVar = 0;
public TestThreadMethod(String name){
super(name);
}
public synchronized void run(){
if(shareVar==0){
for(int i=0; i<5; i++){
shareVar++;
if(shareVar==5){
this.suspend();//(1)
}}}
else{
System.out.print(Thread.currentThread().getName());
System.out.println(" shareVar = " + shareVar);
this.resume();//(2)
}}
}
public class TestThread{
public static void main(String[] args){
TestThreadMethod t1 = new TestThreadMethod("t1");
TestThreadMethod t2 = new TestThreadMethod("t2");
t1.start();//(5)
//t1.start();//(3)
t2.start();//(4)
}}

‘叁’ 在JAVA中怎么实现消息队列

java中的消息队列
消息队列是线程间通讯的手段:

importjava.util.*

publicclassMsgQueue{

privateVectorqueue=null;
publicMsgQueue(){
queue=newVector();
}
publicsynchronizedvoidsend(Objecto)
{
queue.addElement(o);
}
publicsynchronizedObjectrecv()
{
if(queue.size()==0)
returnnull;
Objecto=queue.firstElement();
queue.removeElementAt(0);//orqueue[0]=nullcanalsowork
returno;
}
}

因为java中是lockedbyobject的所以添加synchronized就可以用于线程同步锁定对象
可以作为多线程处理多任务的存放task的队列。他的client包括封装好的task类以及thread类

Java的多线程-线程间的通信2009-08-2521:58
1.线程的几种状态
线程有四种状态,任何一个线程肯定处于这四种状态中的一种:
1)产生(New):线程对象已经产生,但尚未被启动,所以无法执行。如通过new产生了一个线程对象后没对它调用start()函数之前。
2)可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。当一个线程处于可执行状态时,表示它可能正处于线程池中等待排排程器启动它;也可能它已正在执行。如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一定正在执行中。
3)死亡(Dead):当一个线程正常结束,它便处于死亡状态。如一个线程的run()函数执行完毕后线程就进入死亡状态。
4)停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。当处于停滞状态的线程重新回到可执行状态时,它有可能重新执行。如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状态。
2.classThread下的常用函数函数
2.1suspend()、resume()
1)通过suspend()函数,可使线程进入停滞状态。通过suspend()使线程进入停滞状态后,除非收到resume()消息,否则该线程不会变回可执行状态。
2)当调用suspend()函数后,线程不会释放它的“锁标志”。
例11:
{
publicstaticintshareVar=0;
publicTestThreadMethod(Stringname){
super(name);
}
publicsynchronizedvoidrun(){
if(shareVar==0){
for(inti=0;i<5;i++){
shareVar++;
if(shareVar==5){
this.suspend();//(1)
}}}
else{
System.out.print(Thread.currentThread().getName());
System.out.println("shareVar="+shareVar);
this.resume();//(2)
}}
}
publicclassTestThread{
publicstaticvoidmain(String[]args){
TestThreadMethodt1=newTestThreadMethod("t1");
TestThreadMethodt2=newTestThreadMethod("t2");
t1.start();//(5)
//t1.start();//(3)
t2.start();//(4)
}}
运行结果为:
t2shareVar=5
i.当代码(5)的t1所产生的线程运行到代码(1)处时,该线程进入停滞状态。然后排程器从线程池中唤起代码(4)的t2所产生的线程,此时shareVar值不为0,所以执行else中的语句。
ii.也许你会问,那执行代码(2)后为什么不会使t1进入可执行状态呢?正如前面所说,t1和t2是两个不同对象的线程,而代码(1)和(2)都只对当前对象进行操作,所以t1所产生的线程执行代码(1)的结果是对象t1的当前线程进入停滞状态;而t2所产生的线程执行代码(2)的结果是把对象t2中的所有处于停滞状态的线程调回到可执行状态。
iii.那现在把代码(4)注释掉,并去掉代码(3)的注释,是不是就能使t1重新回到可执行状态呢?运行结果是什么也不输出。为什么会这样呢?也许你会认为,当代码(5)所产生的线程执行到代码(1)时,它进入停滞状态;而代码(3)所产生的线程和代码(5)所产生的线程是属于同一个对象的,那么就当代码(3)所产生的线程执行到代码(2)时,就可使代码(5)所产生的线程执行回到可执行状态。但是要清楚,suspend()函数只是让当前线程进入停滞状态,但并不释放当前线程所获得的“锁标志”。所以当代码(5)所产生的线程进入停滞状态时,代码(3)所产生的线程仍不能启动,因为当前对象的“锁标志”仍被代码(5)所产生的线程占有。
#p#2.2sleep()
1)sleep()函数有一个参数,通过参数可使线程在指定的时间内进入停滞状态,当指定的时间过后,线程则自动进入可执行状态。
2)当调用sleep()函数后,线程不会释放它的“锁标志”。
例12:
{
{
publicstaticintshareVar=0;
publicTestThreadMethod(Stringname){
super(name);
}
publicsynchronizedvoidrun(){
for(inti=0;i<3;i++){
System.out.print(Thread.currentThread().getName());
System.out.println(":"+i);
try{
Thread.sleep(100);//(4)
}
catch(InterruptedExceptione){
System.out.println("Interrupted");
}}}
}
publicclassTestThread{publicstaticvoidmain(String[]args){
TestThreadMethodt1=newTestThreadMethod("t1");
TestThreadMethodt2=newTestThreadMethod("t2");
t1.start();(1)
t1.start();(2)
//t2.start();(3)
}}
运行结果为:
t1:0
t1:1
t1:2
t1:0
t1:1
t1:2
由结果可证明,虽然在run()中执行了sleep(),但是它不会释放对象的“锁标志”,所以除非代码(1)的线程执行完run()函数并释放对象的“锁标志”,否则代码(2)的线程永远不会执行。
如果把代码(2)注释掉,并去掉代码(3)的注释,结果将变为:
t1:0
t2:0
t1:1
t2:1
t1:2
t2:2
由于t1和t2是两个对象的线程,所以当线程t1通过sleep()进入停滞时,排程器会从线程池中调用其它的可执行线程,从而t2线程被启动。
例13:
{
publicstaticintshareVar=0;
publicTestThreadMethod(Stringname){
super(name);
}
publicsynchronizedvoidrun(){
for(inti=0;i<5;i++){
System.out.print(Thread.currentThread().getName());
System.out.println(":"+i);
try{
if(Thread.currentThread().getName().equals("t1"))
Thread.sleep(200);
else
Thread.sleep(100);
}
catch(InterruptedExceptione){
System.out.println("Interrupted");
}}
}}
publicclassTestThread{publicstaticvoidmain(String[]args){
TestThreadMethodt1=newTestThreadMethod("t1");
TestThreadMethodt2=newTestThreadMethod("t2");
t1.start();
//t1.start();
t2.start();
}}
运行结果为:
t1:0
t2:0
t2:1
t1:1
t2:2
t2:3
t1:2
t2:4
t1:3
t1:4
由于线程t1调用了sleep(200),而线程t2调用了sleep(100),所以线程t2处于停滞状态的时间是线程t1的一半,从从结果反映出来的就是线程t2打印两倍次线程t1才打印一次。
#p#2.3yield()
1)通过yield()函数,可使线程进入可执行状态,排程器从可执行状态的线程中重新进行排程。所以调用了yield()的函数也有可能马上被执行。
2)当调用yield()函数后,线程不会释放它的“锁标志”。
例14:
{
publicstaticintshareVar=0;
publicTestThreadMethod(Stringname){super(name);
}
publicsynchronizedvoidrun(){for(inti=0;i<4;i++){
System.out.print(Thread.currentThread().getName());
System.out.println(":"+i);
Thread.yield();
}}
}
publicclassTestThread{publicstaticvoidmain(String[]args){
TestThreadMethodt1=newTestThreadMethod("t1");
TestThreadMethodt2=newTestThreadMethod("t2");
t1.start();
t1.start();//(1)
//t2.start();(2)
}
}
运行结果为:
t1:0
t1:1
t1:2
t1:3
t1:0
t1:1
t1:2
t1:3
从结果可知调用yield()时并不会释放对象的“锁标志”。
如果把代码(1)注释掉,并去掉代码(2)的注释,结果为:
t1:0
t1:1
t2:0
t1:2
t2:1
t1:3
t2:2
t2:3
从结果可知,虽然t1线程调用了yield(),但它马上又被执行了。
2.4sleep()和yield()的区别
1)sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。
2)sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。
例15:
{
publicstaticintshareVar=0;
publicTestThreadMethod(Stringname){
super(name);
}
publicvoidrun(){
for(inti=0;i<4;i++){
System.out.print(Thread.currentThread().getName());
System.out.println(":"+i);
//Thread.yield();(1)
/*(2)*/
try{
Thread.sleep(3000);
}
catch(InterruptedExceptione){
System.out.println("Interrupted");
}}}
}
publicclassTestThread{
publicstaticvoidmain(String[]args){
TestThreadMethodt1=newTestThreadMethod("t1");
TestThreadMethodt2=newTestThreadMethod("t2");
t1.setPriority(Thread.MAX_PRIORITY);
t2.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
}
}
运行结果为:
t1:0
t1:1
t2:0
t1:2
t2:1
t1:3
t2:2
t2:3
由结果可见,通过sleep()可使优先级较低的线程有执行的机会。注释掉代码(2),并去掉代码(1)的注释,结果为:
t1:0
t1:1
t1:2
t1:3
t2:0
t2:1
t2:2
t2:3
可见,调用yield(),不同优先级的线程永远不会得到执行机会。
2.5join()
使调用join()的线程执行完毕后才能执行其它线程,在一定意义上,它可以实现同步的功能。
例16:
{
publicstaticintshareVar=0;
publicTestThreadMethod(Stringname){
super(name);
}
publicvoidrun(){
for(inti=0;i<4;i++){
System.out.println(""+i);
try{
Thread.sleep(3000);
}
catch(InterruptedExceptione){
System.out.println("Interrupted");
}
}
}
}
publicclassTestThread{
publicstaticvoidmain(String[]args){
TestThreadMethodt1=newTestThreadMethod("t1");
t1.start();
try{
t1.join();
}
catch(InterruptedExceptione){}
t1.start();
}
}
运行结果为:
0
1
2
3
0
1
2
3
#p#3.classObject下常用的线程函数
wait()、notify()和notifyAll()这三个函数由java.lang.Object类提供,用于协调多个线程对共享数据的存取。
3.1wait()、notify()和notifyAll()
1)wait()函数有两种形式:第一种形式接受一个毫秒值,用于在指定时间长度内暂停线程,使线程进入停滞状态。第二种形式为不带参数,代表waite()在notify()或notifyAll()之前会持续停滞。
2)当对一个对象执行notify()时,会从线程等待池中移走该任意一个线程,并把它放到锁标志等待池中;当对一个对象执行notifyAll()时,会从线程等待池中移走所有该对象的所有线程,并把它们放到锁标志等待池中。
3)当调用wait()后,线程会释放掉它所占有的“锁标志”,从而使线程所在对象中的其它synchronized数据可被别的线程使用。
例17:
下面,我们将对例11中的例子进行修改
{
publicstaticintshareVar=0;
publicTestThreadMethod(Stringname){
super(name);
}
publicsynchronizedvoidrun(){
if(shareVar==0){
for(inti=0;i<10;i++){
shareVar++;
if(shareVar==5){
try{
this.wait();//(4)
}
catch(InterruptedExceptione){}
}
}
}
if(shareVar!=0){
System.out.print(Thread.currentThread().getName());
System.out.println("shareVar="+shareVar);
this.notify();//(5)
}
}
}
publicclassTestThread{
publicstaticvoidmain(String[]args){
TestThreadMethodt1=newTestThreadMethod("t1");
TestThreadMethodt2=newTestThreadMethod("t2");
t1.start();//(1)
//t1.start();(2)
t2.start();//(3)
}}
运行结果为:
t2shareVar=5
因为t1和t2是两个不同对象,所以线程t2调用代码(5)不能唤起线程t1。如果去掉代码(2)的注释,并注释掉代码(3),结果为:
t1shareVar=5
t1shareVar=10
这是因为,当代码(1)的线程执行到代码(4)时,它进入停滞状态,并释放对象的锁状态。接着,代码(2)的线程执行run(),由于此时shareVar值为5,所以执行打印语句并调用代码(5)使代码(1)的线程进入可执行状态,然后代码(2)的线程结束。当代码(1)的线程重新执行后,它接着执行for()循环一直到shareVar=10,然后打印shareVar。
#p#3.2wait()、notify()和synchronized
waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronizedblock中进行调用。如果在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。
例18:
{
publicintshareVar=0;
publicTestThreadMethod(Stringname){
super(name);
newNotifier(this);
}
publicsynchronizedvoidrun(){
if(shareVar==0){
for(inti=0;i<5;i++){
shareVar++;
System.out.println("i="+shareVar);
try{
System.out.println("wait......");
this.wait();
}
catch(InterruptedExceptione){}
}}
}
}
classNotifierextendsThread{
privateTestThreadMethodttm;
Notifier(TestThreadMethodt){
ttm=t;
start();
}
publicvoidrun(){
while(true){
try{
sleep(2000);
}
catch(InterruptedExceptione){}
/*1要同步的不是当前对象的做法*/
synchronized(ttm){
System.out.println("notify......");
ttm.notify();
}}
}
}
publicclassTestThread{
publicstaticvoidmain(String[]args){
TestThreadMethodt1=newTestThreadMethod("t1");
t1.start();
}
}
运行结果为:
i=1
wait......
notify......
i=2
wait......
notify......
i=3
wait......
notify......
i=4
wait......
notify......
i=5
wait......
notify......
4.wait()、notify()、notifyAll()和suspend()、resume()、sleep()的讨论
4.1这两组函数的区别
1)wait()使当前线程进入停滞状态时,还会释放当前线程所占有的“锁标志”,从而使线程对象中的synchronized资源可被对象中别的线程使用;而suspend()和sleep()使当前线程进入停滞状态时不会释放当前线程所占有的“锁标志”。
2)前一组函数必须在synchronized函数或synchronizedblock中调用,否则在运行时会产生错误;而后一组函数可以non-synchronized函数和synchronizedblock中调用。
4.2这两组函数的取舍
Java2已不建议使用后一组函数。因为在调用suspend()时不会释放当前线程所取得的“锁标志”,这样很容易造成“死锁”。

‘肆’ javaweb任务列队怎么做

1.在同一时刻,可能有很多任务需要执行,
而程序在同一时刻只能执行一定数量的任务,
当需要执行的任务数超过了程序所能承受的任务数时怎么办呢?
这就有了先执行哪些任务,后执行哪些任务的规则。
2.TaskQueue类就定义了这些规则中的一种,它采用的是FIFO(先进先出,英文名是First
In
First
Out)的方式,也就是按照任务到达的先后顺序执行。TaskQueue类的定义。

Java任务队列代码如下:

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class TaskQueue
{
private List<Task>
queue = new LinkedList<Task>();
//
添加一项任务

public synchronized void addTask(Task
task) {
if (task
!= null)
{
queue.add(task);
}
}
//
完成任务后将它从任务队列中删除

public synchronized void finishTask(Task
task) {
if (task
!= null)
{
task.setState(Task.State.FINISHED);
queue.remove(task);
}
}
//
取得一项待执行任务

public synchronized Task
getTask() {
Iterator<Task>
it = queue.iterator();
Task
task;
while (it.hasNext())
{
task
= it.next(); //
寻找一个新建的任务
if (Task.State.NEW.equals(task.getState()))
{ //
把任务状态置为运行中
task.setState(Task.State.RUNNING);
return task;
}
}
return null;
}
}

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class TaskQueue
{
private List<Task>
queue = new LinkedList<Task>();
//
添加一项任务
public synchronized void addTask(Task
task) {
if (task
!= null)
{
queue.add(task);
}
}
//
完成任务后将它从任务队列中删除

public synchronized void finishTask(Task
task) {
if (task
!= null)
{
task.setState(Task.State.FINISHED);
queue.remove(task);
}
}
//
取得一项待执行任务

public synchronized Task
getTask() {
Iterator<Task>
it = queue.iterator();
Task
task;
while (it.hasNext())
{
task
= it.next(); //
寻找一个新建的任务
if (Task.State.NEW.equals(task.getState()))
{ //
把任务状态置为运行中
task.setState(Task.State.RUNNING);
return task;
}
}
return null;
}
}

‘伍’ 到底什么是消息队列Java中如何实现消息队列

“消息队列”是在消息的传输过程中保存消息的容器。和我们学过的LinkedHashMap,TreeSet等一样,都是容器。既然是容器,就有有自己的特性,就像LinkedHashMap是以键值对存储。存取顺序不变。而消息队列,看到队列就可以知道。这个容器里面的消息是站好队的,一般遵从先进先出原则。

java中已经为我们封装好了很多的消息队列。在java 1.5版本时推出的java.util.concurrent中有很多现成的队列供我们使用。特性繁多,种类齐全。是你居家旅游开发必备QAQ。

下面简单列举这个包中的消息队列

  1. :阻塞队列 BlockingQueue

  2. 数组阻塞队列 ArrayBlockingQueue

  3. 延迟队列 DelayQueue

  4. 链阻塞队列 LinkedBlockingQueue

  5. 具有优先级的阻塞队列 PriorityBlockingQueue

  6. 同步队列 SynchronousQueue

  7. 阻塞双端队列 BlockingDeque

  8. 链阻塞双端队列 LinkedBlockingDeque

    不同的队列不同的特性决定了队列使用的时机,感兴趣的话你可以详细了解。具体的使用方式我就不赘述了

‘陆’ java 线程池 工作队列是如何工作的

使用线程池的好处

1、降低资源消耗

可以重复利用已创建的线程降低线程创建和销毁造成的消耗。

2、提高响应速度

当任务到达时,任务可以不需要等到线程创建就能立即执行。

3、提高线程的可管理性

线程是稀缺资源,如果无限制地创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一分配、调优和监控

线程池的工作原理

首先我们看下当一个新的任务提交到线程池之后,线程池是如何处理的

1、线程池判断核心线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行任务。如果核心线程池里的线程都在执行任务,则执行第二步。

2、线程池判断工作队列是否已经满。如果工作队列没有满,则将新提交的任务存储在这个工作队列里进行等待。如果工作队列满了,则执行第三步

3、线程池判断线程池的线程是否都处于工作状态。如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务

线程池饱和策略

这里提到了线程池的饱和策略,那我们就简单介绍下有哪些饱和策略:

AbortPolicy

为Java线程池默认的阻塞策略,不执行此任务,而且直接抛出一个运行时异常,切记ThreadPoolExecutor.execute需要try catch,否则程序会直接退出。

DiscardPolicy

直接抛弃,任务不执行,空方法

DiscardOldestPolicy

从队列里面抛弃head的一个任务,并再次execute 此task。

CallerRunsPolicy

在调用execute的线程里面执行此command,会阻塞入口

用户自定义拒绝策略(最常用)

实现RejectedExecutionHandler,并自己定义策略模式

下我们以ThreadPoolExecutor为例展示下线程池的工作流程图

3.jpg

关键方法源码分析

我们看看核心方法添加到线程池方法execute的源码如下:

// //Executes the given task sometime in the future. The task //may execute in a new thread or in an existing pooled thread. // // If the task cannot be submitted for execution, either because this // executor has been shutdown or because its capacity has been reached, // the task is handled by the current {@code RejectedExecutionHandler}. // // @param command the task to execute // @throws RejectedExecutionException at discretion of // {@code RejectedExecutionHandler}, if the task // cannot be accepted for execution // @throws NullPointerException if {@code command} is null // public void execute(Runnable command) { if (command == null) throw new NullPointerException(); // // 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. // 翻译如下: // 判断当前的线程数是否小于corePoolSize如果是,使用入参任务通过addWord方法创建一个新的线程, // 如果能完成新线程创建exexute方法结束,成功提交任务 // 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. // 翻译如下: // 在第一步没有完成任务提交;状态为运行并且能否成功加入任务到工作队列后,再进行一次check,如果状态 // 在任务加入队列后变为了非运行(有可能是在执行到这里线程池shutdown了),非运行状态下当然是需要 // reject;然后再判断当前线程数是否为0(有可能这个时候线程数变为了0),如是,新增一个线程; // 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. // 翻译如下: // 如果不能加入任务到工作队列,将尝试使用任务新增一个线程,如果失败,则是线程池已经shutdown或者线程池 // 已经达到饱和状态,所以reject这个他任务 // int c = ctl.get(); // 工作线程数小于核心线程数 if (workerCountOf(c) < corePoolSize) { // 直接启动新线程,true表示会再次检查workerCount是否小于corePoolSize if (addWorker(command, true)) return; c = ctl.get(); } // 如果工作线程数大于等于核心线程数 // 线程的的状态未RUNNING并且队列notfull if (isRunning(c) && workQueue.offer(command)) { // 再次检查线程的运行状态,如果不是RUNNING直接从队列中移除 int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) // 移除成功,拒绝该非运行的任务 reject(command); else if (workerCountOf(recheck) == 0) // 防止了SHUTDOWN状态下没有活动线程了,但是队列里还有任务没执行这种特殊情况。 // 添加一个null任务是因为SHUTDOWN状态下,线程池不再接受新任务 addWorker(null, false); } // 如果队列满了或者是非运行的任务都拒绝执行 else if (!addWorker(command, false)) reject(command); }

‘柒’ JAVA中,常用的队列实现是哪个

队列的实现单纯的是数据结构的问题,既可以用链表结构实现队列,也可以用数组实现。这和语言不是紧密关系,java可以这样实现,c、c++
也可以。

‘捌’ java中如何实现按队列执行任务

package com.tone.example;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.tone.task.TaskProperty;
import com.tone.task.TaskSignature;
import com.tone.task.impl.BasicTask;
import com.tone.task.runner.TaskRunner;

/**
* 任务队列示例程序
* @author zlf
*/
public class TaskExample {
private TaskRunner taskRunner;

/**
* 做任务队列的初始化工作
*/
@Before
public void init() {
// 获取任务运行器
taskRunner = TaskRunner.getInstance();
// 将任务运行器放入线程进行调度
Thread thread = new Thread(taskRunner);
thread.start();
}

/**
* 等待任务执行完成,并做最后的退出工作
*/
@After
public void exit() throws InterruptedException {
Thread.sleep(600);
System.exit(0);
}

/**
* 最简单的任务运行示例
*/
@Test
public void example1() {
// 添加任务到任务运行器
taskRunner.addTask(new BasicTask() {
@Override
public void run() {
System.out.println("This is running in task runner thread, and thread is " + Thread.currentThread());
}
});
}

/**
* 加入优先执行顺序的任务运行器
*/
@Test
public void example2() {
// 添加任务到任务运行器
taskRunner.addTask(new BasicTask(0) {
@Override
public void run() {
System.out.println("This is a normal task");
}
});
taskRunner.addTask(new BasicTask(-1) {
@Override
public void run() {
System.out.println("This is a task a bit high than normal");
}
});
}

/**
* 重复添加的任务只会运行第一个
*/
@Test
public void example3() {
// 添加任务到任务运行器
taskRunner.addTask(new BasicTask(TaskSignature.ONE) {
@Override
public void run() {
System.out.println("This is task one");
}
}, TaskProperty.NOT_REPEAT);
taskRunner.addTask(new BasicTask(TaskSignature.ONE) {
@Override
public void run() {
System.out.println("This is also task one");
}
}, TaskProperty.NOT_REPEAT);
}

/**
* 重复添加的任务只会运行最后一个
*/
@Test
public void example4() {
// 添加任务到任务运行器
taskRunner.addTask(new BasicTask(TaskSignature.ONE) {
@Override
public void run() {
System.out.println("This is task one");
}
}, TaskProperty.NOT_REPEAT_OVERRIDE);
taskRunner.addTask(new BasicTask(TaskSignature.ONE) {
@Override
public void run() {
System.out.println("This is also task one");
}
}, TaskProperty.NOT_REPEAT_OVERRIDE);
}
}

‘玖’ java 队列

我说一种情况吧。队列可以用于数据缓冲,比如你一个线程接收数据,这个数据可能会一段时间来的非常迅猛,一段时间又来的比较温和,这个时候你就可以做一个队列,一个线程把接收的数据存放到队列,另外的线程慢慢处理数据,在数据来的迅猛的时候,因为有队列的缓冲,你处理数据的线程就算处理不过,也不会直接导致系统崩溃,等数据来的温和的时候,就可以慢慢的消化之前在队列来不及处理的数据。

‘拾’ java队列实现异步执行

在整个思路上要调整一下

1、会有很多线程给一个队列上添加任务

2、有一个或者多个线程逐个执行队列的任务


考虑一下几点:

1、没有任务时,队列执行线程处于等待状态

2、添加任务时,激活队列执行线程,全部run起来,首先抢到任务的执行,其他全部wait


给个小例子吧

packageorg;
importjava.util.LinkedList;
importjava.util.List;
publicclassQueues{
publicstaticList<Task>queue=newLinkedList<Task>();
/**
*假如参数o为任务
*@paramo
*/
publicstaticvoidadd(Taskt){
synchronized(Queues.queue){
Queues.queue.add(t);//添加任务
Queues.queue.notifyAll();//激活该队列对应的执行线程,全部Run起来
}
}
staticclassTask{
publicvoidtest(){
System.out.println("我被执行了");
}
}
}
packageorg;
importjava.util.List;
{
@Override
publicvoidrun(){
while(true){
synchronized(Queues.queue){
while(Queues.queue.isEmpty()){//
try{
Queues.queue.wait();//队列为空时,使线程处于等待状态
}catch(InterruptedExceptione){
e.printStackTrace();
}
System.out.println("wait...");
}
Queues.Taskt=Queues.queue.remove(0);//得到第一个
t.test();//执行该任务
System.out.println("end");
}
}
}
publicstaticvoidmain(String[]args){
Exece=newExec();
for(inti=0;i<2;i++){
newThread(e).start();//开始执行时,队列为空,处于等待状态
}
//上面开启两个线程执行队列中的任务,那就是先到先得了
//添加一个任务测试
Queues.Taskt=newQueues.Task();
Queues.add(t);//执行该方法,激活所有对应队列,那两个线程就会开始执行啦
}

}


上面的就是很简单的例子了

热点内容
按键脚本优化 发布:2024-05-19 04:59:57 浏览:751
怎么下载压缩包 发布:2024-05-19 04:47:47 浏览:9
二嫂水仙ftp 发布:2024-05-19 04:47:42 浏览:160
云隙服务器下载 发布:2024-05-19 04:33:22 浏览:315
德国C语言 发布:2024-05-19 04:13:40 浏览:965
音频管理器没有文件夹 发布:2024-05-19 04:13:36 浏览:667
qq邮箱端口993服务器怎么填 发布:2024-05-19 04:07:05 浏览:204
javaapi框架 发布:2024-05-19 04:06:59 浏览:365
与存储结构无关的术语 发布:2024-05-19 04:05:41 浏览:500
编译路由器固件选择 发布:2024-05-19 03:56:28 浏览:42