有没有办法在不创建单独的线程的情况下执行定时器?

时间:2018-02-26 01:50:12

标签: java multithreading

我的情况是我需要每1秒为当前正在执行的线程增加一个Thread局部变量。例如,请考虑以下代码段

public class DemoApplication {

    public static final ThreadLocal<Integer> threadTest =
        new ThreadLocal<Integer>() {
            @Override protected Integer initialValue() {
                return 1;
            }
        };

    public static void main(String[]args) {
        Timer timer = new Timer();
        timer.schedule(new timerTask(), 0, 1000);

        DummyApplication2 DM2 = new DummyApplication2();
        DM2.start();

        while(true) {
            try{
                System.out.println("main thread test value" + threadTest.get());
                Thread.sleep(2000);
            }
            }catch (InterruptedException e) {
                System.out.println("Thread interrupted in main");
            }

        }
    }
}
class timerTask extends TimerTask{

    private int i= 0;
    public void run() {
        DemoApplication.threadTest.set(i);
        i+=1;
    }
}


class DummyApplication2 extends Thread{
    public void run() {
        while (true) {
            try {
                Thread.sleep(1000);
                System.out.println("Second thread test value " + DemoApplication.threadTest.get());
            } catch(InterruptedException e){
                System.out.println("Got interrupted exception");
            }
        }
    }
}

上面的代码创建了两个线程,并创建了一个每1秒执行一次计划任务的计时器。

但是对于上面的情况,因为timerTask正在一个单独的线程上执行,它不会为仍在运行的其他两个线程增加线程本地计数器threadTest。解决这个问题的一种方法是迭代可用的运行线程列表,但是我不确定如果线程数量不断增加会有多高效(结果也不正确,例如在上面的代码中{{1}类线程局部变量的增量应该是主线程的两倍,因为它与main相比只睡了半个时间。

所以我想知道是否有任何方法可以创建一个可以在当前正在执行的线程而不是在自己的线程中运行的计时器。

对此有任何帮助都很棒,谢谢

2 个答案:

答案 0 :(得分:1)

  

所以我想知道是否有办法创建一个可以的计时器   在当前正在执行的线程中运行,而不是在自己的线程中运行。

没有

但是,您可以记录开始时间,然后检查该线程中的当前时间以查看已经过了多长时间。它不是一个计时器而是一个时钟。然后,当你关心这个价值时,只需看看时间并计算它应该是什么。

您也可以在本地启动计时器线程,以便它可以直接访问变量并直接更新它。因此,线程1启动线程2,线程2启动线程3,线程3更新线程2中的值。但是,通常睡眠线程不是计时的好方法。

答案 1 :(得分:0)

一个解决方案是每秒运行一个守护程序线程并检查线程是否正在运行并更新增量编号。对于此解决方案,您需要由线程工厂管理或创建包装器,可以为线程提供唯一的名称或ID当守护程序线程更新count时用作键。对于存储,您可以使用键值数据结构,如Map。

优化到上面的解决方案您创建的每个线程都会传递一个具有开始和结束方法的侦听器类。当线程启动时,它会通知metrics类,它将启动一个仪表增加直到停止方法调用。当线程停止时,它将调用end方法。所以动态地你可以计算增量。