是否必须同步线程的字符串字段上的getter和setter /

时间:2015-03-11 14:03:05

标签: java multithreading atomicity

我正在制作一个可以做一些独立工作的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");
        }
    }
}

2 个答案:

答案 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可能是避免数据过于陈旧的好主意。