精华内容
下载资源
问答
  • 一般来说,要判断多线程的任务是否完全结束可以使用Thread.activeCount()方法,它可以得出现在运行的线程数(不是进程)。如果要判断所有建立的线程已经结束,那么只剩一个main线程,count应该为1。但是有些时候会...

    一般来说,要判断多线程的任务是否完全结束可以使用Thread.activeCount()方法,它可以得出现在运行的线程数(不是进程)。如果要判断所有建立的线程都已经结束,那么只剩一个main线程,count应该为1。但是有些时候会失效,这次由于判断不对导致我debug了好久才知道原因。
    利用
    Thread.currentThread().getThreadGroup().list();
    语句来输出现在运行的线程:
    在这里插入图片描述
    可以看到,有四个线程正在运行,第一个是main主函数的运行,第二个是IDEA自带的(可能)检测信号的线程,所以大部分情况下得到的count是2。
    而后两个一个是我用的GUI线程,一个是尚未关闭的Timer线程。
    所以正常情况下应该判断为2,而不是大多数IDE的1,如果加了GUI等有其他线程的功能还要再向上加。

    展开全文
  • 但是我无法判断第一步开出的15个线程是否结束,我只能手工屏蔽第二和第三部分代码,然后依次执行。 高手有什么办法没,如何判断15个线程是否结束。 就是如何<span style="color: red">...
  • Android 多线程判断线程结束最近在做多线程断点线程的时候,遇到一个问题,因为需要在多线程下载完成时候,对文件进行处理,而处理肯定是在文件下载完成时候,而下载完成时候肯定是多线程都完成时候,所以怎么判断...

    Android 多线程之判断线程结束

    最近在做多线程断点线程的时候,遇到一个问题,因为需要在多线程下载完成时候,对文件进行处理,而处理肯定是在文件下载完成时候,而下载完成时候肯定是多线程都完成时候,所以怎么判断多线程完成呢?也是百度了很多文章,也都试了试。但是都发现不能解决自己的问题。

    没有解决问题的方案

    1.线程池 然后shutdown 然后判断是否terminate,如果terminate返回为true,就是完成了。

    例子代码如下

    exe.shutdown();

    System.out.println("shutdown():启动一次顺序关闭,执行以前提交的任务,但不接受新任务。");

    while(true){

    if(exe.isTerminated()){

    System.out.println("所有的子线程都结束了!");

    break;

    }

    Thread.sleep(1000);

    }

    这个方案在Android不行,不知道在java那边可以不,因为shutdown会让线程自动关闭,但是它的关闭,不是等线程正常的做完事情关闭,而是暴力的让他关闭了。如果我们的线程是下载东西的话,他就是在还没有下载完成或者在下载中就让关闭了,这个不是我们想要的。

    2.CountDownLatch 先初始化,线程数的声明。然后在每个线程结束时候。线程数方法减一,然后在外面等待,当线程数减为0的时候,等待后面的代码执行。

    这个方法也试了试,可惜在Android还是不行,因为会在等待的那个地方报错,说你需要锁住线程,但是CountDownLatch 这个类没有什么锁住方法,无奈也不行。

    思考

    经过上面2个失败的解决例子后,我有了点启发尤其是针对第一种方式,因为在上次面试的时候,有个面试官,问了一个我没有遇到的问题,就是如何取消一个线程池的方法,我当时没有答出来,后来回去百度了下,原来在线程池声明的时候,是可以使用future这个对象来得到线程对象的。所以这里的突破口也觉得是应该在线程池这里。

    查阅线程池方法时候,的确是有返回线程池状态的方法,可惜不是熟悉的thread和runable对象而是callable,其实callable和runable几乎差不多,就是能够返回一个值,而runable不能,这个值就是我们想要的,如果我们的每个线程在结束时候返回我们定义的结束的值,那么我们在线程结束时候,判断他们的值不是就知道,我们的线程是否结束了吗?思路有了就开始,实现。

    1.首先把runable接口换成callable接口,然后在定义返回的值。

    2.判断线程结束时候的线程状态,然后取出每个值,判断值是不是我们正常结束的。(这里还有一个点是,怎么判断这个时间点呢?我们找到了future对象的get方法。他返回值的时候就是说明线程结束时候。无论是正常结束还是异常结束。)

    代码如下(这里是下载的代码和只是思路):下载代码的改造

    public static class DownLoadThread implements Callable {

    private int threadId;

    private int startBlock;

    private int endBlock;

    private String downUrl;

    private String storePath;

    private String version;//解决下载中断,不同版本的切换问题

    public DownLoadThread(int i, int startBlock, int endBlock, String url, String storePath, String version) {

    this.threadId = i;

    this.startBlock = startBlock;

    this.endBlock = endBlock;

    this.downUrl = url;

    this.storePath = storePath;

    this.version = version;

    }

    @Override

    public Integer call() {

    try {

    URL url = new URL(downUrl);

    HttpURLConnection con = (HttpURLConnection) url.openConnection();

    con.setRequestMethod("GET");

    con.setConnectTimeout(10 * 1000);

    File file = new File(storePath.substring(0, storePath.lastIndexOf("/")), version + "_" + threadId + ".txt");

    RandomAccessFile downLoadAss = null;

    if (file != null && file.exists()) {

    downLoadAss = new RandomAccessFile(file, "rwd");

    String lastPositon = downLoadAss.readLine();

    if (null == lastPositon || "".equals(lastPositon)) {

    this.startBlock = startBlock;

    } else {

    if (lastPositon != null && !"".equals(lastPositon)) {

    startBlock = Integer.parseInt(lastPositon) - 1;

    }

    }

    } else {

    downLoadAss = new RandomAccessFile(file, "rwd");

    }

    con.setRequestProperty("Range", "bytes=" + startBlock + "-" + endBlock);

    if (con.getResponseCode() == 206) {//请求部分成果

    InputStream input = con.getInputStream();

    RandomAccessFile randomAccessFile = new RandomAccessFile(new File(storePath), "rwd");

    randomAccessFile.seek(startBlock);

    byte[] bytes = new byte[1024 * 4];

    int length = -1;

    int total = 0;

    while ((length = input.read(bytes)) != -1) {

    randomAccessFile.write(bytes, 0, length);

    total += length;

    downLoadAss.seek(0);

    downLoadAss.write(String.valueOf(startBlock + total).getBytes("UTF-8"));

    }

    downLoadAss.close();

    randomAccessFile.close();

    input.close();

    // Log.e("show", "线程" + threadId + "下载关闭");

    File f = new File(storePath.substring(0, storePath.lastIndexOf("/")), version + "_" + threadId + ".txt");

    f.delete();//删除记录下载的文件

    return 1;

    }

    } catch (MalformedURLException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    return 0;

    } catch (IOException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    return 0;

    }

    return 1;

    }

    }

    判断线程状态和读取每个future对象返回的值。

    ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1);

    List downLoadThreads = new ArrayList<>();

    for (int i = 0; i < threadCount; i++) {

    int startBlock = i * blockSize;

    int endBlock = (i + 1) * blockSize - 1;

    if (i == threadCount - 1) {//如果是最后一个线程,下载完

    endBlock = fileLength - 1;

    }

    downLoadThreads.add(new DownLoadThread(i, startBlock, endBlock, downUrl, storePath, version));

    }

    try {

    List> futures = executorService.invokeAll(downLoadThreads);

    for (Future future : futures) {

    if (future.get() == 1) {//这里会等待 阻塞线程 1是成功的标识

    currentRunThreadCount = currentRunThreadCount - 1;//还没有完成的进程

    }

    }

    if (currentRunThreadCount == 0) {

    return 1;

    }

    使用了线程池对象,然后使用invokeAll方法得到线程池每个线程的future列表,然后循环读取future列表的方法值,时机是future的get方法,这个点会一直等到当前线程做完结束,如果是我们值,我们把判断线程数的值减一,当线程数判断值为零时候,就是说所有线程都完成时候。

    展开全文
  • 判断@Async注解下所有线程是否结束

    千次阅读 2020-01-12 11:18:38
    springboot 判断@Async注解下所有线程是否结束 因为在项目中想知道程序运行的时间,百度只有判断单线程结束的方法,所以记录下自己的解决方案 **//这是一个带有回调的多线程函数** @Async public Future<...

    springboot 判断@Async注解下所有线程是否结束

    因为在项目中想知道程序运行的时间,百度都只有判断单线程结束的方法,所以记录下自己的解决方案

    //这是一个带有回调的多线程函数
    @Async
        public Future<String> getWaterValveInfo(String tableName) {
         //方法略
            return new AsyncResult<>( "任务完成");
        }
    
     public void getAllInformatin() throws ExecutionException, InterruptedException {
            System.out.println("开始运行" + new Date());
            List<HashMap<String, Object>> mapList = labMapper.selectAll();
            //定义一个存所有线程回调函数的list
            List<Future<String>> futureList=new ArrayList<>();
            List<String> tableNameList=new ArrayList<>();
            long start=System.currentTimeMillis();
            if (!mapList.isEmpty()) {
                for (int i = 0; i < mapList.size(); i++) {
                    String tableName = String.valueOf(mapList.get(i).get("machinename")).trim();
                    //将回调的信息存入list中
                            futureList.add(insertMongo.getWaterValveInfo(tableName));
                    }
                }
                **//判断进程是否全部结束**
                while (true){
                **//回调信息空了就结束**
                    if (futureList.isEmpty()){
                        break;
                    }
                    for (int i = 0; i < futureList.size(); i++) {
                        if (futureList.get(i).isDone()){
                        //判断线程结束,输出回调信息,并将该回调清除
                            System.out.println(futureList.get(i).get());
                            futureList.remove(i);
                        }else {
                            continue;
                        }
                    }
                }
                System.out.println("任务完成,耗时:"+ (System.currentTimeMillis()-start)+"ms");
            }
        }
    
    展开全文
  • 我就废话不说了,大家还是直接看代码吧~上面是主线程的代码,创建了一个能同时执行2个线程的线程池,并投入5个线程,当5个线程都执行完毕后打印---“结束了!”字符串。exe.shutdown();该方法在加入线程队列的...

    我就废话不多说了,大家还是直接看代码吧~

    上面是主线程的代码,创建了一个能同时执行2个线程的线程池,并投入5个线程,当5个线程都执行完毕后打印---“结束了!”字符串。

    exe.shutdown();该方法在加入线程队列的线程执行完之前不会执行。exe.isTerminated()当shutdown()或者shutdownNow()执行了之后才会执行,并返回true。

    在上面的代码中必须有exe.isTerminated()的判断,否则在投入5个线程到线程池后会直接打印:“结束了”。不能达到我们想要的效果。

    通过while(true)循环判断exe.isTerminated()的值,为了防止过多的判断浪费资源,可设置线程睡眠Thread.sleep(200);正是由于这个睡眠,所以当所有线程池中的线程都执行完后,有可能延迟200ms才执行"结束了"语句。这个参数越小延迟越小,结果越准确。

    下面是子线程,子线程只是简单的将数字i打印出来;

    执行结果:

    3

    1

    4

    5

    2

    结束了!

    成功构建 (总时间: 2 秒)

    子线程执行顺序不能控制,所以输出的结果是乱序的。

    补充知识:java如何禁掉反射

    SecurityManager

    有一个checkMemberAccess这个方法可以阻止利用反射;

    如:

    SecurityManager sm = new SecurityManager();

    sm.checkMemberAccess(Test.class, Member.PUBLIC);

    前面一个为CLASS,后面需要填一个INT值,Member.PUBLIC 代表可以访问,

    如果是PUBLIC,反射可以执行,DECLARED,反射运行时,会报错。

    SecurityManager另外一个例子:

    以上这篇Java 判断线程池所有任务是否执行完毕的操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。

    原文链接:http://blog.chinaunix.net/uid-29368697-id-4065665.html

    展开全文
  • 新创建的线程默认是前台线程,如果某个线程对象在启动之前调用了setDaemon(true)语句,这个线程就变成了一个后台线程。 说明: 在Java程序中,只要有一个前台线程在运行,这个... //判断是否为后台线程 System.
  • 最近在学python,对于多线程执行时,主线程是否会主动等着子线程结束后才结束,还是主线程先结束也没关系,子线程会继续执行完毕说法不一,我自己试了,代码如下。 先说结论: 1、主线程可以先于子线程结束,但仅仅...
  • ????使用 ThreadGroup,首先创建一个线程组,把创建的子线程放到这个线程组里,然后循环判断这个线程组的活跃线程数量 是否等于0,不等于0继续,否则代表子线程全部执行完了,进行下一步。
  • 可以通过Isbackground 属性来判断线程是否是后台线程。 进程以这种形式终止的时候,后台线程执行栈中的finally块就不会在执行了。 如果想让他执行,可以在退出程序时使用join来等待后台线程(如果是你自己创建的...
  • 有一种解决方式,便是在子线程下载完成之后,进行子线程的回调并判断是否所有子线程已经执行完毕。 而CountDownLatch便是java在1.5提供的解决如上问题的工具类 阿里的ARouter的拦截器相关,就是用该工具类 概述 ...
  • WorkspaceRunner这个转换器想必不少朋友用到过,它的作用是在一个工作空间中执行另外一个工作空间,当然这还不是关键,关键是他可以同时开7个fme.exe的线程,在我们的计算机硬件配置足够强大,内存cpu足够强大的...
  • java多线程下载

    2014-05-27 11:13:54
    1.得到服务器下载文件的大小,然后在本地设置一个临时文件和服务器端文件大小...5.当你的n个线程都下载完毕的时候我进行删除记录下载位置的缓存文件 a)线程下载完就减去 b)当没有正在运行的线程时切文件存在时删除文件
  • boost库多线程特性

    2017-04-13 22:59:35
    时候,线程不仅仅是执行一些耗时操作,可能我们... 当线程执行到某一个点时,进行轮训,判断是否所有线程执行到该点,单独开启了一个线程用于轮训所有线程是否结束,  待所有线程结束后会获取数据,生成一个文
  • isAlive()和join()的使用我们之前说到,最好让主线程最后结束,在前面的例子中,是通过调用sleep()方法,让线程睡眠产生时差来实现的,经过足够长时间...有两个方法可以判断一个线程是否已经结束。第一,可以在线...
  • 在delphi中如何判断线程终止

    千次阅读 2010-08-29 00:25:00
    我做了一个线程队列,用队列管理线程,可是无法得知哪个线程是否结束了,然后让结束了的线程重新启动? Obj: TQueryThread 用delphi的TThread类实现 用什么方法可知线程结束了,我用线程句柄,有...
  • 业务描述:用多线程循环向一个账户充值1元,测试账户余额是否正常。 ... 三个不同package:1、只有...线程执行结束判断语句:如果executorService.isShutdown()和executorService.isTerminated()为true,则执行结束
  • Python多线程通信问题

    2020-01-18 09:20:58
    新人第一次提问, 最近在学习Python多线程, notify()与wait()语句。这是我写的一个作业, 要求是: 现在的你,是一个农场主。农场中养着10头小牛,牛吃草长大,但只有当下雨的时候草才会长大,每天有20%的概率下雨,草...
  • Python 3 之多线程研究

    千次阅读 2011-11-11 08:52:10
    2.主线程要等到所有新开的子线程结束后才能结束,这个用到了Threading中的isAlive()方法,来判断线程是否还存活 3.不能出现开了个子线程,却被一个抢着CPU执行时间,这个学过操作系统的知道time.sl
  • 3. 如何判断线程结束? 4. 如何控制线程结束? 下面就这几个问题提出解决方法: 1. 线程数量我们可以通过for循环来实现,就如同当年初学编程的打点程序一样。 比如已知用户指定了n(它是一个int型变量)个线程吧,...
  • 该项目的大体逻辑是这样的,启动K个线程,当线程执行到某一个点时,进行轮训,判断是否所有线程执行到该点,单独开启了一个线程用于轮训所有线程是否结束,待所有线程结束后会获取数据,生成一个文件,另外还有一...
  • 用BlockingQueue 做了一个多线程的程序, 每个线程已经执行完run方法(通过print显示已经执行完run), 并且在主线程里做了一个for循环来判断几个线程的状态, 得到他们已经是TERMINATED状态,但是主线程就是不...
  • 因为需要操作UI,所以在子线程里调用invoke,但是无论使用invoke还是beginInvoke,那个加载内容的函数是在UI线程上执行。这样就会造成UI线程阻塞。 想实现的效果是,一次点击之后马上能响应下一次点击同时把上一次...
  • [color=red]我在一个 while循环的 多线程查询 程序 中[/color] 出现了 个问题, ServiceThread st = new ServiceThread(url, "a web service thread"); st.start(); 这个线程 没 把 自己run方法 完全 执行完...
  • (我是利用循环来判断就绪队列当中是否存在就绪进程的) 除此之外,我在每次循环末结束时都会VBox.getChildren().remove()一下,但是这些remove()效果会在退出整个循环的时候才出现而不是每次循环结束都出现,不知其中...
  • Java中断线程学习小结

    2020-05-20 15:31:17
    目标线程检测到isInterrupted()为true或者捕获了InterruptedException应该立刻结束自身线程。 通过标志位判断需要正确使用volatile关键字。 volatile关键字解决了共享变量在线程间的可见性问题。 更具体...
  • 在开发项目中因为for循环中的逻辑执行需要很长时间,为了提高效率使用了多线程,有考虑到如果循环数量过大 每次循环产生新线程会产生性能问题甚至会服务器崩掉,所以使用了线程池对线程数量进行控制。 但在执行...
  • 而Java堆和方法区不一样,一个接口的个实现类需要的内存不一样,一个方法的个分支需要的内存也可能不一样,我们只有在程序运行的时候才知道会创建那些对象,这部分内存的分配和回收是动态的,垃圾收集主要所...
  • 它利用信号灯来判断线程是否可以执行,可以避免线程的死锁问题 在java中,生产者与消费者模式是必须通过同步synchronized才可以实现的   下面的代码中有两种不近相同的该模式代码展示(Movie,...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 152
精华内容 60
关键字:

多线程判断线程是否都结束