我有一段代码,每 5 秒生成一个新线程,每个线程定期打印出计数器的值。它总共启动最多 10 个线程。
代码如下:
public static void main(String[] args) {
ScheduledExecutorService task = Executors.newScheduledThreadPool(10);
AtomicInteger counter = new AtomicInteger(0);
int i = 0;
while (i < 10) {
// sleep 5 seconds
sleep(5);
task.scheduleAtFixedRate(() -> {
String threadName = Thread.currentThread().getName();
int newCounter = counter.get();
System.out.println(String.format("[%s] counter = %d" , threadName, newCounter));
}, 0, 2, TimeUnit.SECONDS);
counter.getAndIncrement();
++i;
}
}
private static void sleep(int sleepTime) {
try {
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException ie) {
}
}
这是输出:
[pool-1-thread-1] counter = 1
[pool-1-thread-1] counter = 1
[pool-1-thread-2] counter = 1
[pool-1-thread-3] counter = 1
[pool-1-thread-1] counter = 2
[pool-1-thread-2] counter = 2
[pool-1-thread-4] counter = 2
[pool-1-thread-5] counter = 2
[pool-1-thread-3] counter = 2
[pool-1-thread-1] counter = 3
[pool-1-thread-7] counter = 3
[pool-1-thread-6] counter = 3
[pool-1-thread-8] counter = 3
[pool-1-thread-4] counter = 3
[pool-1-thread-9] counter = 3
[pool-1-thread-5] counter = 3
[pool-1-thread-10] counter = 3
[pool-1-thread-1] counter = 4
.......
我希望每个线程都打印出其原始值,例如,pool-1-thread-1应该始终打印出0或1(取决于计数器是先递增还是线程先启动),第二个线程应该持久地发出先前的计数器+1,...如下所示:
[pool-1-thread-1] counter = 1
[pool-1-thread-1] counter = 1
[pool-1-thread-2] counter = 2
[pool-1-thread-3] counter = 3
[pool-1-thread-1] counter = 1
[pool-1-thread-2] counter = 2
[pool-1-thread-4] counter = 4
[pool-1-thread-5] counter = 5
[pool-1-thread-3] counter = 3
[pool-1-thread-1] counter = 1
[pool-1-thread-7] counter = 7
.......
我的问题是如何使 newCounter 局部变量在每个线程中保持其原始值。我能想到的方法是将线程名称到其原始值的映射存储在线程安全哈希表中。有没有更清洁的方法来实现这一点?谢谢
最佳答案
要将值绑定(bind)到特定线程,您可以使用 ThreadLocal多变的。
javadoc 中的 ThreadId
示例类可以轻松调整来解决您的用例。
public static void main(String[] args) {
ScheduledExecutorService task = Executors.newScheduledThreadPool(10);
AtomicInteger counter = new AtomicInteger(0);
ThreadLocal<Integer> id = ThreadLocal.withInitial(counter::incrementAndGet);
int i = 0;
while (i < 10) {
// sleep 5 seconds
sleep(5);
task.scheduleAtFixedRate(() -> {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("[%s] counter = %d" , threadName, id.get()));
}, 0, 2, TimeUnit.SECONDS);
++i;
}
}
private static void sleep(int sleepTime) {
try {
TimeUnit.SECONDS.sleep(sleepTime);
} catch (InterruptedException ie) {
}
}
关于java - 如何在多线程程序中保存线程变量的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50360604/