想实现的目的是,主线程可能在等待10秒钟,让子线程A和B去分别完成某个任务,有可能由于某个原因,A和B执行所需的时间会不同,但是我想他们两者其中一个完成之后就马上唤醒主线程(如果是A先完成了,那么主线程就不等待B),然后主线程继续去执行其他任务。如果过去10秒钟,A和B都没完成任务,那么主线程就唤醒,继续完成其他的任务
请问一下大家有什么方式可以实现呢?thx
import java.util.concurrent.Future;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.List;
import java.util.ArrayList;
public class Test{
public static void main(String[] args){
Task A = new Task("A");
Task B = new Task("B");
Object o = new Object();
Server server = new Server(o,A,B);
Thread serverThread = new Thread(server);
serverThread.start();
synchronized(o){
try{
o.wait(10000);//线程等待10秒
serverThread.interrupt();//中断线程
}catch(InterruptedException e){
e.printStackTrace();
System.exit(1);
}
}
System.out.println("Main: finished!");
}
}
class Task implements Callable<String>{
public Task(String name){
this.name = name;
}
@Override
public String call()throws Exception{
long duration = (long)(Math.random() * 20);//设置随机等待时间.
System.out.printf("%s: Waiting %d seconds for processing!\n",name,duration);
try{
TimeUnit.SECONDS.sleep(duration);
}catch(InterruptedException e){
return null;
}
System.out.printf("%s: Finished!\n",name);
return name;
}
private String name;
}
class Server implements Runnable{
public Server(Object o,Task ... tasks){
this.o = o;
for(Task task : tasks){
taskList.add(task);
}
}
@Override
public void run(){
try{
executor.invokeAny(taskList);
}catch(InterruptedException|ExecutionException e){
}finally{
executor.shutdown();
}
synchronized(o){
o.notifyAll();
}
}
private ExecutorService executor = Executors.newCachedThreadPool();
private List<Task> taskList = new ArrayList<>();
private final Object o;
}
public class Test{
public static void main(String[] args){
Task task = new Task("A");
MyThread threadA = new MyThread(task,"A");
MyThread threadB = new MyThread(task,"B");
threadA.start();
threadB.start();
Object synObject = new Object();
ConditionThread condition = new ConditionThread(synObject,threadA,threadB);
condition.start();//监控线程
synchronized(synObject){
try{
synObject.wait(10000);//主线程等待10秒
}catch(InterruptedException e){
}
//10秒后中断线程A和线程B
threadA.interrupt();
threadB.interrupt();
}
}
}
class ConditionThread extends Thread{
//这个线程是监控线程.一旦发现传入的线程中有某个已经优先完成.那么将中断剩余的线程.
public ConditionThread(Object synObject,MyThread ... threads){
this.threads = threads;
this.synObject = synObject;
}
@Override
public void run(){
while(true){
for(int i = 0 ; i < threads.length ; i ++){
if(threads[i].getCondition()){
for(int j = 0 ; j < i ; j ++ ){
threads[j].interrupt();
}
for(int j = i + 1 ; j < threads.length ; j ++){
threads[j].interrupt();
}
synchronized(synObject){
synObject.notifyAll();
}
return;
}
}
}
}
private MyThread[] threads;
private Object synObject;
}
class MyThread extends Thread{
public MyThread(Runnable task,String name){
super(task,name);
}
@Override
public void run(){
super.run();
condition = true;
}
public boolean getCondition(){
//判断改线程是否已经完成.
return condition;
}
private boolean condition = false;
}
class Task implements Runnable{
public Task(String str){
this.str = str;
}
@Override
public void run(){
long duration = (long)(Math.random() * 50);//注:这里可以时间长些,一旦线程需要的均时间超过10秒,那么main线程等待10秒后将中断该线程
System.out.printf("%s: waiting %d seconds for processing.\n",Thread.currentThread().getName(),duration);
try{
Thread.sleep(duration * 1000);
}catch(InterruptedException e){
return;
}
System.out.printf("%s: finish!\n",Thread.currentThread().getName());
}
private String str;
}
class MyRunnable implements Runnable {
private int i = 0;
@Override
public void run() {
// TODO Auto-generated method stub
while (i < 10) {
System.out.println(Thread.currentThread().getName() + ":" + i);
i++;
}
if(i==10){
System.out.println("---------"+Thread.currentThread().getName()+"唤醒主线程-------------");
synchronized (Test1.obj) {
Test1.obj.notify();
}
}
}
}
class MainThread implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (Test1.obj) {
System.out.print("主线程开始运行。。。。 ");
try {
System.out.println("主线程被挂起10s。。。。");
Test1.obj.wait(10*1000);
System.out.println("主线程继续运行。。。。");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
//测试类
public class Test1 {
public static final Object obj = new Object();
public static void main(String[] args) {
// TODO Auto-generated method stub
new Thread(new MainThread()).start();
MyRunnable mr = new MyRunnable();
Thread t1 = new Thread(mr, "A");
Thread t2 = new Thread(mr, "B");
t1.start();
t2.start();
}
}
第90行代码中.你可以把时间设置小些.比如20秒内随机,然后可以看看效果
刚测试了一下使用T = ExecutorService.invokeAny(Callable<T>)这种方式,确实能够满足到我的要求,十分感谢。
不过我有个地方比较纠结的是,对于线程的中途打断,后台会报大量各种各样的异常,包括数据库链接(执行的任务中有需要链接数据库)还有其他等等。除了这种打断其他线程的方式,能不能不打断,就让它运行,只是不管后面执行完的线程,就让它自动销毁
那你可以把线程设置成守护线程.让main执行完毕后也跟随停止就可以了.但是除非是线程只是读操作。如果多个线程都是写操作的话那么还是存在某段时间的不确定性操作的.特别如果你的需求是满足多个写操作线程一个完成其他结束的情况下.
哪怕是用invokeAny这个方法实际上实现也是用interrupt这种方式.因为线程的stop方法由于有一定的缺陷所以java已经不建议使用了.
使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待。 java.util.concurrent.CountDownLatch 使用countDownLatch.await()方法非常简单的完成...
问题描述 ...2:主线程X需要在子线程A和B执行完成之后再执行 方案1 1)思路 使用join()方法实现 2)代码实现 先定义一个线程A,代码如下: public class ThreadA implements Runnable {` public void r...
import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ExcetuorDemo2 { public static void main(String
使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待。 CountDownLatch是一个同步辅助工具,用于使一个或多个线程等待(即阻塞)知道一组在...
java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成了之后才会返回给用户...
主线程等待多个子线程执行完才继续执行,以下是我能想到的几种方法,欢迎讨论、指正。1.闭锁CountDownLatch闭锁是典型的等待事件发生的同步工具类,将闭锁的初始值设置为与子线程数目相同,每个子线程执行完成都调用...
java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成了之后才会返回给用户...
情况1:正常情况下,主线程启动了子线程,主线程、子线程各自执行,彼此不受影响。 当你在运行一个应用的时候,这个时候系统会开一个进程。然后这个进程启动了Main线程。Java进程确定虚拟机中没有线程运行的时候,...
在某些情况下,主线程创建并启动了子线程,如果子线程中需要进行大量的耗时运算,主线程往往将早于子线程结束之前结束,如果主线程想等待子线程执行完毕后,获得子线程中的处理完的某个数据,就要用到join方法了,...
这段时间在项目中遇到了线程的问题,方法体是有返回值的,在方法体内调用了一个线程,最后有数据统计,所以会出现子线程没有执行完成的情况下,主线程就已经走完了,导致数据统计不完整,为了拿到完整的数据,故有...
Java主线程等待所有子线程执行完毕在执行,其实在我们的工作中经常的用到,比如说主线程要返回一个响应用户的值,但这个值得赋值过程是由过个子线程来完成的(模拟一个实际开发的情景),所以主线程必须等待子线程...
线程池工具类:import java.util.concurrent.*;public class CommonThreadPool { private static ExecutorService exec = new ThreadPoolExecutor(50, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue
本文为博主原创文章,未经博主允许不得转载。 ... java在子线程与主线程传递数据 1.代码中用到的类介绍 C:拥有两个方法分别是设置value和获得value,拥有一个私有变量valu...
在主线程复杂逻辑中,有时候想获取网络数据或者其他一些必须放在子线程中操作的业务时,一般都要新开线程,等待线程执行完成之后使用Handler发送到主线程,然后主线程再往下执行,这样的多次切换会造成逻辑复杂难懂....
首先明确线程代码的边界。其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界。Runnable接口中run方法原型如下: public void run(); 而所有的具体线程都实现这个方法,所以这里就...
java实现多个子线程执行完毕后,再执行主线程一、业务场景1、 在做批量数据处理时,需执行多个存储过程。 执行1个存储过程,大概需10分钟,若一个一个的执行,将会耗时很久。 经过测试发现,数据库资源够用,具备...
from time import ctime import threading import time def a(): #for i in range(5): print('Program a is running... at ', ctime(),u'.线程名为:',threading.current_thread().name ) time.slee...
如标题,此功能主要是JDK1.5引入的java.util.concurrent包下的CountDownLatch类,此类据介绍为以线程辅助类,通过线程计数器来实现一个或多个主线程等待其下所有子线程执行完后主线程再继续执行的功能。 该类只在...
正常情况下,如果不做特殊的处理,在主线程中是不能够捕获到子线程中的异常的。例如下面的情况。package com.xueyou.demo.theadexceptiondemo; public class ThreadExceptionRunner implements Runnable{ @...
博主昨天去一家公司面试,被面试官问到一个问题,如果开启10个线程,但是需要这10个线程都执行完成后,再交由主线程统一输入,如何实现?当时我没有回答,我对多线程并不是那么的熟悉,面试结束后,我通过查阅资料...
public class TestThread extends Thread ... System.out.println(this.getName() + "子线程开始"); try { // 子线程休眠五秒 Thread.sleep(5000); } catch (InterruptedException e) {
一直搞不明白Java线程里的join()方法。API给出的解释是: Waits for this thread to die. 那你为啥不叫die()或者waitToDie()或者block()? join明明是参加、结合的意思嘛。 一直苦闷了很久。 今天查知乎后终于明白了...
实现线程的方式有两种: 1、继承java.lang.Thread,并重写它的... ==多线程的执行逻辑: 当主线程被挂起时, 其它就绪的线程会根据选择最 实现线程的方式有两种: 1、继承java.lang.Thread,并重写它的run()方法,
1、最常见的情况,主线程中开启了一个子线程,开启之后,主线程与子线程互不影响各自的生命周期,即主线程结束,子线程还可以继续执行;子线程介素,主线程也能继续执行。 测试代码如下: public class TestThread...
Java主线程等待所有子线程执行完毕在执行,这个需求其实我们在工作中经常会用到,比如用户下单一个产品,后台会做一系列的处理,为了提高效率,每个处理都可以用一个线程来执行,所有处理完成了之后才会返回给用户...
在面试时,经常会有面试官问道,如何将
文本将介绍两种可以优雅的终止线程的方式…第一种在JAVA《Java多线程模式》中有一种叫Two-Phase Termination(两步终止)的模式可以优雅的终止线程,这种模式采用了两个步骤来终止线程,所以叫两步终止模式。...
这里记录一下下面这种情况:主线程需要等待多个子线程执行完后再执行。 1.使用CountDownLatch 示例如下,我们初始化一个CountDownLatch,值为10(子线程个数),然后每次一个子线程执行完后执行一下countDown()...
shutdown ...SecurityException - 如果安全管理器存在并且关闭,此 ExecutorService 可能操作某些不允许调用者修改的线程(因为它没有保持RuntimePermission("modifyThread")),...
visio_2016下载安装,亲测可用,不需要破解,而且无秘钥。简单方便实用