仅与一个线程同步是必需的

时间:2015-10-09 14:54:54

标签: java multithreading thread-safety

如果我有一个使用静态方法扩展Thread的类(这非常简化):

public class MyThread extends Thread {

    private static long SLEEP_INT = 30000;
    private static Map<Integer, String> myData;

    //every 30 seconds, update map of data
    public void run() {
        while(isActive) {
            try {
                populateDataFromDB();
                Thread.sleep( SLEEP_INT );
            }
            catch( Exception e ) {
                //do nothing
            }
        }
    }

    //static method to update map of data
    public static void populateDataFromDB() {
        //do stuff here, setting values in myData
    }
}

然后在我的应用程序的其他地方我有:

MyThread.populateDataFromDB();

如果我知道我的应用程序中只有一个 MyThread 类的实例,是否仍然需要在 populateDataFromDB 中编写同步代码以确保线程安全

2 个答案:

答案 0 :(得分:2)

您确实需要同步,因为您将有多个线程正在访问MyThread.myData中保存的数据。您向我们展示了一个线程,它将定期从您的数据库中读取并填写您的地图。如果你有什么东西可以利用这些数据,你只会这样做。

您不希望使用Map的线程看到半填充的地图,或者包含不一致状态的地图。为了安全起见,您需要使用同步来防止线程在myData线程每30秒更新一次时读取MyThread

换句话说,仅仅因为您只有一个给定类的实例并不一定意味着您不需要同步。您需要同步,因为您有多个线程(每个可能运行不同的代码)访问相同的数据。您可能允许数据的所有读者同时访问数据,但在写入数据结构的操作期间确保独占访问。

答案 1 :(得分:2)

不,当你只有一个线程时,你永远不需要同步。 (主线程是应用程序中的第一个线程)

但是当您从主线程执行thread.start时,系统中有2个线程。如果由于某种原因,您的线程(新线程和主线程)正在尝试写入两个线程都可以访问的内存,那么您希望序列化该共享内存上的线程访问。如何序列化访问是同步有用的地方。

因此,在您的示例中,如果populateDataFromDB尝试修改该共享数据,并且我假设您可以从新线程(内部运行)中调用它,并且您还想从主线程访问该populateDataFromDB(我假设如您所说& #34;然后在我的应用程序的其他地方我有:&#34;),那么你肯定需要同步。

相关问题