【问题标题】:Java Thread : Multithreading - Race conditionJava 线程:多线程 - 竞争条件
【发布时间】:2016-10-12 07:28:55
【问题描述】:

我正在编写可以同时从多个用户访问的多线程程序,并且该程序必须避免竞争条件。

代码/多线程:

public class DataProcessor implements Serializable, Runnable {

private static final long serialVersionUID = 1L;

public DataProcessor() {

}

@Override
public void run() {
    process();
}

private void process() {

    int iSize = 5;

    for (int iCounter = 0; iCounter < iSize; iCounter++) {
        DataKey objDataKey = new DataKey();
        ArrayList<String> list = //..fetch data method ()
        HashMap<String, String> hmPQdata = //..fetch data method ()

        SendNForgotHelperThread helperThread = new SendNForgotHelperThread(objDataKey, list, hmPQdata);
        Thread t = new Thread(helperThread);
        t.start();
    }

}

class SendNForgotHelperThread implements Runnable {

    private ArrayList<String> list;
    private HashMap<String, String> hmPQdata;
    private DataKey objDataKey;

    public SendNForgotHelperThread(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) {
        this.list = list;
        this.hmPQdata = hmPQdata;
        this.objDataKey = objDataKey;
    }

    @Override
    public void run() {

        try {

            // Option 1 : synchronized method - SendNForgotHelperThread class object locking

            DataCollector objDataSenderM = new DataCollector();
            objDataSenderM.synchronizedMethodStore(this.objDataKey, this.list, this.hmPQdata);

            // Option 2 : synchronized block - SendNForgotHelperThread class object locking

            synchronized (this) {
                DataCollector objDataSender = new DataCollector();
                objDataSender.store(this.objDataKey, this.list, this.hmPQdata);
            }

            // Option 3 : Class level locking

            synchronized (SendNForgotHelperThread.class) {
                DataCollector objDataSender = new DataCollector();
                objDataSender.store(this.objDataKey, this.list, this.hmPQdata);
            }

        } catch (Exception iex) {
            System.out.println("Exception in thread: " + iex.getMessage());
        }
    }
}

class DataCollector {

    public void store(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) {

        HashMap<String, String> retrivedValue = (HashMap<String, String>) MemCacheUtil
                .retrieveFromMemCache(objDataKey.getKey());

        retrivedValue.putAll(hmPQdata);

        MemCacheUtil.addToMemCache(objDataKey.getKey(), retrivedValue, "expTime value");

        // Sending data in queue
        sendDataToQueue(objDataKey, list, hmPQdata);

    }

    synchronized void synchronizedMethodStore(DataKey objDataKey, ArrayList<String> list,
            HashMap<String, String> hmPQdata) {
        store(objDataKey, list, hmPQdata);

    }

}

class DataKey {
    private String key;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }
}

public void sendDataToQueue(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) {
    // sending data to queue

}

}

用户 1:

public class UserA {

public static void main(String[] args) {
    DataProcessor objDataProcessor = new DataProcessor();
    Thread thProcessorThread = new Thread(objDataProcessor, "PROCESSOR");
    thProcessorThread.start();
}

}

用户 2:

public class UserB {

public static void main(String[] args) {
    DataProcessor objDataProcessor = new DataProcessor();
    Thread thProcessorThread = new Thread(objDataProcessor, "PROCESSOR");
    thProcessorThread.start();
}

}

用户 A 和 B 将同时调用 DataProcessor 线程。 很明显,选项 1 和 2 将面临竞争条件,因为它们正在锁定该类的对象/自身类对象锁定,而选项 3 将提供类级别的锁定 - 如果多个用户将同时访问该程序,那么选项 3 将减慢应用程序和多线程的整个目的将继续折腾。

任何人都可以就如何处理这种情况提供任何阅读建议。

编辑:

任何人都可以帮助处理 SendNForgotHelperThread 线程对象上的竞争条件 - 这个线程是从循环中调用的,并且每个循环都会启动新线程 SendNForgotHelperThread。

【问题讨论】:

    标签: java multithreading locking threadpool semaphore


    【解决方案1】:

    您将DataProcessor 的两个不同实例传递给UserAUserB 类中的线程,如果您启动这些主要方法,它将正常运行。竞争条件不会出现在您的应用程序中。

    要发生竞争条件,您必须传递共享对象,即多个线程对同一个对象进行操作,并且共享对象应该具有字段/属性以在多个线程之间共享

        DataProcessor objDataProcessor = new DataProcessor();
        Thread thProcessorThread1 = new Thread(objDataProcessor, "PROCESSOR-1");
        thProcessorThread1.start();
        Thread thProcessorThread2 = new Thread(objDataProcessor, "PROCESSOR-2");
        thProcessorThread2.start();
    

    【讨论】:

    • 请检查 SendNForgotHelperThread 线程的 5 个实例 - 这将有竞争条件
    • 不会的,process 方法会为每个线程创建一个 SendNForgotHelperThread 的新实例,这两个 objDataProcessor 实例是独立的,您可以将同一个对象共享给多个线程进行竞赛-条件。
    • 那么选项 1 或选项 2 将是正确的以避免竞争条件,并且应该删除第 3 个选项,因为它是类级别锁定并且会减慢应用程序?
    • 没有。如果您使用的是 IDE,请在代码中设置断点并进行调试,您就会明白会发生什么
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 2013-08-26
    • 1970-01-01
    相关资源
    最近更新 更多