我正在制作一个可以做一些独立工作的Runnable,但是其他线程会跟着它的进展。
为了做到这一点,我把一个私有字符串字段包含"状态"我的线程。线程将使用此字段的setter更新其进程,其他线程将使用getter检索状态。 目前,我编写了以下代码,并使用锁定来同步我的getter和setter。 但我想知道是否有必要。
我想我的问题可以概括为: "在Java"
中,做作是否是原子的如果你花时间阅读我的问题,请提前感谢。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class FollowedThread implements Runnable {
private String state;
private final Lock lock;
public FollowedThread() {
lock = new ReentrantLock();
}
public void setState(String state) {
lock.lock();
try {
this.state = state;
} finally {
lock.unlock();
}
}
public String getState() {
String result;
lock.lock();
try {
result = state;
} finally {
lock.unlock();
}
return result;
}
@Override
public void run() {
setState("Step 1 running");
try {
Thread.sleep(1000);
setState("Step 2 running");
Thread.sleep(2000);
setState("Step 3 running");
Thread.sleep(3000);
setState("Thread finished");
} catch (InterruptedException e) {
setState("Thread interrupted");
}
}
}
答案 0 :(得分:1)
我想我找到了答案。 为了确保对字段的原子访问,您必须声明它volatile。 有了它我的代码变成了:
package com.afklm.myactu.util;
public class FollowedThread implements Runnable {
private volatile String state;
public void setState(String state) {
this.state = state;
}
public String getState() {
return state;
}
@Override
public void run() {
setState("Step 1 running");
try {
Thread.sleep(1000);
setState("Step 2 running");
Thread.sleep(2000);
setState("Step 3 running");
Thread.sleep(3000);
setState("Thread finished");
} catch (InterruptedException e) {
setState("Thread interrupted");
}
}
}
答案 1 :(得分:0)
没有必要。没有什么会被破坏,因为这是一个原子操作。最糟糕的情况是你的getter会得到一个旧值。原子操作不需要锁定。
现在最大的问题是,吸气剂获得绝对最近的价值有多重要?如果这与其他同步相关联,则可能。将volatile
关键字添加到state
可能是避免数据过于陈旧的好主意。