MultipleThreading |后来的线程覆盖ThreadLocal值

时间:2017-05-30 08:02:57

标签: java multithreading

我编写了一个多线程处理程序,我在while循环中创建线程实例,每个线程都有一个local variables的单独副本,如下所示:

while(cond.){
    ...
            //calling thread class constructor with local parameters
            ad = AddDoc.getInst(count, connection, userDetails, documentClass, uploadDoc, propMap, b, mimType, folderId, existingDocList, nonexistingDocList, errorDocList, mimType, bhamashahId);
            ad.start();
    ...
}

上面的代码为每个文档上传操作创建一个新线程。

现在我正在使用ThreadLocalThread class中运行多个主题,如下所示:

class AddDoc extends Thread {

    private ThreadLocal<Object> context = new ThreadLocal<Object>();

    ...
    some other variables
    ...
    Map<String, String> propMap = new HashMap<String,String>();

    private List<Object> list;

    public AddDoc(int count, CEConnection connection, String[] userDetails, String documentClass, boolean uploadDoc, Map<String, String> propMap1, byte[] b, String mimetype, String folderId, List<String> existingDocList, List<String> nonexistingDocList, List<String> errorDocList, String sessionUser, String bhamashahId) {

        list = new ArrayList<Object>();
        list.add(propMap1);
        list.add(connection);
        list.add(userDetails);
        list.add(documentClass);
        list.add(uploadDoc);
        list.add(b);
        list.add(mimetype);
        list.add(folderId);
        list.add(sessionUser);
        list.add(bhamashahId);

    }

    public Object getTransactionId() {
        return context.get();
    }

    @Override
    public void run() {
        context.set(list);

        //calling getTransactionId() method and retrieving the stored List
        List<Object> runList = ( ArrayList<Object> )getTransactionId();

        //Retrieving Map stored in List
        Map<String,String> runMap = (Map<String,String>)runList.get(0);

        ..somewhere down a few line of codes..
        //printing Map values
        logger.info("Map in Thread > "+runMap);
}
}

问题

run()方法中打印地图时,我收到后来在Map块中调用的线程的while

这意味着初始化的2个线程,后来调用的第二个线程,overrides存储在Map中的ThreadLocal完全根据我违反了ThreadLocal的概念。< / p>

我错误地使用 ThreadLocal 吗?请建议。

谢谢

1 个答案:

答案 0 :(得分:0)

线程之间只应该有一个ThreadLocal共享实例。

您应该使private static final字段对所有Thread实例可见,或者向所有线程注入单个ThreadLocal实例。

为了将来的参考,javadoc应该提供足够的信息来使用任何Java API类:

  

此类提供线程局部变量。这些变量不同   来自他们的正常对应者,每个访问一个的线程   (通过其get或set方法)有自己的,独立初始化   变量的副本。 ThreadLocal实例通常是私有   希望将状态与线程关联的类中的静态字段   (例如,用户ID或交易ID)。