首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Java线程中监听特定的时间?

如何在Java线程中监听特定的时间?
EN

Stack Overflow用户
提问于 2018-06-22 23:03:44
回答 2查看 117关注 0票数 0

我正在创建多个线程,我希望每个线程在其BlockingQueue中监听任何新消息2秒,然后消失。我使用了以下代码:

代码语言:javascript
复制
public class Main {
    public static void main(String[] argv) throws Exception {
        int capacity = 10;
        BlockingQueue<String> queue = new ArrayBlockingQueue<String>(capacity);

        ArrayList<String> names = new ArrayList<String>();
        names.add("Apple"); names.add("Banana"); names.add("Mango");
        HashMap<String, Worker> workermap = new HashMap<String, Worker>();
        for (String name: names) {
            Worker a_worker = new Worker(queue);
            a_worker.setName(name);
            a_worker.start();
            workermap.put(name, new Worker(queue));
        }
        queue.put("Hello ");
    }
}

class Worker extends Thread {
    BlockingQueue<String> q;

    Worker(BlockingQueue<String> q) {
        this.q = q;
    }

    public void run() {
        try {
            long start = System.currentTimeMillis();
            long end = start + 2*1000;
            while (true) {
                String x = q.take();
                if(System.currentTimeMillis()>=end){
                    System.out.println("No new message since two seconds, killing thread " + this.getName());
                    Thread.interrupted();
//                    break;
                }
//                if (x == null) {
//                    break;
//                }

                System.out.println(x + "from " + this.getName());
            }

        } catch (InterruptedException e) {
        }
    }
}

我希望输出是这样的:

代码语言:javascript
复制
Hello from Apple
Hello from Banana
Hello from Mango
No new message since two seconds, killing thread Apple
No new message since two seconds, killing thread Banana
No new message since two seconds, killing thread Mango

但我只得到了Hello from Apple,然后就什么都没有了。该过程继续进行,没有任何进一步的输出。除了使用计时器终止线程之外,我还尝试检查队列元素是否为空,但没有成功。我哪里错了?

EN

回答 2

Stack Overflow用户

发布于 2018-06-22 23:23:09

如前所述,您需要使用interrupt而不是thread (),而且您不能使用Thread.interrupted();来使用池。您需要使用Thread.currentThread().interrupt();。此外,您不需要检查时间,因为BlockingQueue#poll将等待2秒。

代码语言:javascript
复制
    while (!Thread.currentThread().isInterrupted()) {
        String x = q.poll(2, TimeUnit.SECONDS);
       if (x == null)
         System.out.println("No new message since two seconds, killing thread " + this.getName());
        Thread.currentThread().interrupt();
        System.out.println(x + "from " + this.getName());
    }

输出:

代码语言:javascript
复制
No new message since two seconds, killing thread Mango
Hello from Mango
No new message since two seconds, killing thread Apple
nullfrom Apple
No new message since two seconds, killing thread Banana
nullfrom Banana

编辑:然而,我相信你根本不需要循环。只要下面的代码就可以很好地为你工作。

代码语言:javascript
复制
public void run() {
    try {
        String x = q.poll(2, TimeUnit.SECONDS);
        if (x == null)
          System.out.println("No new message since two seconds, killing thread " + this.getName());
        System.out.println(x + "from " + this.getName());
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}
票数 1
EN

Stack Overflow用户

发布于 2018-06-23 02:48:58

我只是试着对你的代码进行最小限度的修复:

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Main {
    public static void main(String[] argv) throws Exception {
        int capacity = 10;
        BlockingQueue<String> queue = new ArrayBlockingQueue<String>(capacity);

        ArrayList<String> names = new ArrayList<String>();
        names.add("Apple"); names.add("Banana"); names.add("Mango");
        for (String name: names) {
            Worker a_worker = new Worker(queue);
            a_worker.setName(name);
            a_worker.start();
        }
        queue.put("Hello");
        queue.put("Bonjour");
    }
}

class Worker extends Thread {
    BlockingQueue<String> q;

    Worker(BlockingQueue<String> q) {
        this.q = q;
    }

    public void run() {
        long start = System.currentTimeMillis();
        long end = start + 2; //just wait for two milliseconds

        while (true) {
            String x = q.poll();
            if(x != null) {
                System.out.println(x + " from " + this.getName());
            } else if(System.currentTimeMillis() >= end){
                System.out.println("No new message since two milliseconds, killing thread " + this.getName());
                interrupt();
            }

            if(interrupted()) {
                break;
            }
        }
    }
}

示例输出:

代码语言:javascript
复制
Hello from Apple
No new message since two milliseconds, killing thread Banana
Bonjour from Mango
No new message since two milliseconds, killing thread Apple
No new message since two milliseconds, killing thread Mango
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50990795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档