Java ExecutorService中队列中的最大等待时间
有没有办法设置Executor服务的最大等待时间 例如,当您将两个while true runnable传递给Java ExecutorService中队列中的最大等待时间,java,multithreading,Java,Multithreading,有没有办法设置Executor服务的最大等待时间 例如,当您将两个while true runnable传递给SingleThreadExecutor时,第一个将永远工作,第二个将永远等待 我希望得到一个关于第二个Runnable的TimeOutException public static void main(String[] args) throws IOException { ExecutorService executor = Executors.newSingleThr
SingleThreadExecutor
时,第一个将永远工作,第二个将永远等待
我希望得到一个关于第二个Runnable的TimeOutException
public static void main(String[] args) throws IOException {
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 2; i++) {
int finalI = i;
executor.execute(new Runnable() {
@Override
public void run() {
while (true) {
try {
System.out.println("#"+ finalI + " Runnable !");
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
}
publicstaticvoidmain(字符串[]args)引发IOException{
ExecutorService executor=Executors.newSingleThreadExecutor();
对于(int i=0;i<2;i++){
int finalI=i;
executor.execute(新的Runnable(){
@凌驾
公开募捐{
while(true){
试一试{
System.out.println(“#”+finalI+“Runnable!”);
睡眠(1000);
}捕获(例外e){
e、 printStackTrace();
}
}
}
});
}
}
您的执行器只有一个线程。它将在内部对不同的可运行任务进行排队,并尝试逐个完成它们。如果第一个任务从未完成(因为这是一个while-true循环),那么第二个任务将永远不会启动
您可以使用submit
而不是execute
来获取未来的对象,并执行带有超时的get
操作
public static void main(String[] args) throws IOException {
ExecutorService executor = Executors.newSingleThreadExecutor();
List<Future> future = new ArrayList<>();
for (int i = 0; i < 2; i++) {
int finalI = i;
future.add(executor.submit(new Runnable() {
@Override
public void run() {
while (true) {
try {
System.out.println("#"+ finalI + " Runnable !");
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}));
}
// Check if second task finishes in the next 2 seconds, and throw a TimeoutException if it does not
try {
future.get(1).get(2000, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
e.printStackTrace();
}
}
如果所有线程都忙,此Executor服务将自动拒绝任务 您的执行器只有一个线程。它将在内部对不同的可运行任务进行排队,并尝试逐个完成它们。如果第一个任务从未完成(因为这是一个while-true循环),那么第二个任务将永远不会启动 您可以使用
submit
而不是execute
来获取未来的对象,并执行带有超时的get
操作
public static void main(String[] args) throws IOException {
ExecutorService executor = Executors.newSingleThreadExecutor();
List<Future> future = new ArrayList<>();
for (int i = 0; i < 2; i++) {
int finalI = i;
future.add(executor.submit(new Runnable() {
@Override
public void run() {
while (true) {
try {
System.out.println("#"+ finalI + " Runnable !");
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}));
}
// Check if second task finishes in the next 2 seconds, and throw a TimeoutException if it does not
try {
future.get(1).get(2000, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
e.printStackTrace();
}
}
如果所有线程都忙,此Executor服务将自动拒绝任务
有没有办法设置Executor服务的最大等待时间
如果您谈论的是等待作业开始运行,那么答案很不幸是“不容易”。有一些方法可以使用ThreadPoolExecutor
中的队列来完成,但它们会被视为黑客,不推荐使用。您还可以扩展ThreadPoolExecutor
,但这可能会变得复杂
一个[更好的]解决方案是从外部管理队列
// synchronous queue waits for someone to take() from the queue before returning
final BlockingQueue<Runnable> jobQueue = new SynchronousQueue<Runnable>();
...
// submit all of your threads who get jobs from your queue to run
executor.execute(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread.isInterrupted()) {
try {
Runnable job = jobQueue.take();
job.run();
} catch (InterruptedException ie) {
// always recommended
Thread.currentThread().interrupt();
return;
}
}
}
});
...
// now we can try to add a job into the queue but if it is full, offer may timeout
if (!queue.offer(new Runnable() { ... }, 2000, TimeUnit.SECONDS)) {
// timed out
}
//同步队列在返回之前等待有人从队列中取出()
final BlockingQueue jobQueue=new SynchronousQueue();
...
//提交从队列中获取作业的所有线程以运行
executor.execute(新的Runnable(){
@凌驾
公开募捐{
而(!Thread.currentThread.isInterrupted()){
试一试{
Runnable job=jobQueue.take();
job.run();
}捕获(中断异常ie){
//一直推荐
Thread.currentThread().interrupt();
返回;
}
}
}
});
...
//现在我们可以尝试将作业添加到队列中,但如果作业已满,则可能会超时
if(!queue.offer(new Runnable(){…},2000,TimeUnit.SECONDS)){
//超时
}
希望这有帮助
有没有办法设置Executor服务的最大等待时间
如果您谈论的是等待作业开始运行,那么答案很不幸是“不容易”。有一些方法可以使用ThreadPoolExecutor
中的队列来完成,但它们会被视为黑客,不推荐使用。您还可以扩展ThreadPoolExecutor
,但这可能会变得复杂
一个[更好的]解决方案是从外部管理队列
// synchronous queue waits for someone to take() from the queue before returning
final BlockingQueue<Runnable> jobQueue = new SynchronousQueue<Runnable>();
...
// submit all of your threads who get jobs from your queue to run
executor.execute(new Runnable() {
@Override
public void run() {
while (!Thread.currentThread.isInterrupted()) {
try {
Runnable job = jobQueue.take();
job.run();
} catch (InterruptedException ie) {
// always recommended
Thread.currentThread().interrupt();
return;
}
}
}
});
...
// now we can try to add a job into the queue but if it is full, offer may timeout
if (!queue.offer(new Runnable() { ... }, 2000, TimeUnit.SECONDS)) {
// timed out
}
//同步队列在返回之前等待有人从队列中取出()
final BlockingQueue jobQueue=new SynchronousQueue();
...
//提交从队列中获取作业的所有线程以运行
executor.execute(新的Runnable(){
@凌驾
公开募捐{
而(!Thread.currentThread.isInterrupted()){
试一试{
Runnable job=jobQueue.take();
job.run();
}捕获(中断异常ie){
//一直推荐
Thread.currentThread().interrupt();
返回;
}
}
}
});
...
//现在我们可以尝试将作业添加到队列中,但如果作业已满,则可能会超时
if(!queue.offer(new Runnable(){…},2000,TimeUnit.SECONDS)){
//超时
}
希望这有帮助。我也知道;),但是得到一个TimeOutException呢?!不会有超时。但是,您可以使用
submit
而不是execute
来接收未来。然后您可以执行future.get(1000,TimeUnit.MILLSECONDS)
,如果任务的执行没有按时完成,它将抛出TimeoutException。我可以扩展我的答案来展示一些实现这种行为的代码:)如果您能给我展示一个有用的示例代码,我将不胜感激。future.get()
等待作业完成。它不会阻止提交作业。在使用服务时,您仍然必须阻止主线程等待答复,以查看线程池是否繁忙(类似于我的future.get()检查)。唯一的区别是,在我的例子中,你实际提交了工作,并检查了它的状态,在@Gray的回答中,你检查了你是否可以提交工作。我猜一切都将取决于您的应用程序架构,如果您想在发送任务后立即阻止,@Gray的回答应该更好。如果您想执行其他逻辑并稍后检查任务是否完成,我的方法应该会执行得更好。我也知道;),但是得到一个TimeOutException呢?!不会有超时。但是,你可以