在java中通过子线程编辑主线程对象



我有一个主线程,在其中我定义了一个HashMap对象。现在在主线程中,我正在创建N个线程。现在,每个线程都将其结果附加到主线程的HashMap对象中并终止。我尝试在构造函数中传递HashMap对象,但当我这样做时,每个线程都会制作一个HashMap对象的本地副本并对其进行编辑。这个更改不会保存在主线程的HashMap对象中。我该怎么办?

在我的主要班级

ThreadParallel threads[] = new ThreadParallel[N];
HashMap<Integer, String> map = new HashMap<Integer, String>();
for(int i=0;i<N;i++)
{
 threads[i] = new ThreadParallel(map);
}

现在处于ThreadParallel类

public class ThreadParallel implements Runnable{
HashMap<Integer, String> map;
Thread t;
public ThreadParallel(HashMap<Integer, String> map) {
          this.map = map;
      t = new Thread(this);
      t.start();
}
@Override
public void run() {    
      // adding data
}
}

这不是最好的设计,但在主类中使映射公开和静态,并在线程类中访问它如何。此外,使用concurrentHashMap将消除同步问题。

ThreadParallel threads[] = new ThreadParallel[N];
public static ConcurrentMap<Integer, String> map = new ConcurrentHashMap<Integer, String>();
for(int i=0;i<N;i++)
{
 threads[i] = new ThreadParallel(map);
}

ThreadParallel类

public class ThreadParallel implements Runnable{
Thread t;
public ThreadParallel() {
      t = new Thread(this);
      t.start();
}
@Override
public void run() {    
      // adding data by accessing the main class map in static way
      // something lik  MainClass.map.put(1,"test");
} 
}

您的代码是正确的。ThreadParallel不创建新的HashMap,而是保存对主线程的HashMap的引用。

我真的不认为线程在制作本地副本,碰巧HashMap不是线程安全的,尝试用ConcurrentHashMap(java.util.concurrent.CurrentHashMap)替换HashMap,方法如下:

ThreadParallel threads[] = new ThreadParallel[N];
Map<Integer, String> map = new ConcurrentHashMap<Integer, String>();
for(int i=0;i<N;i++) {
    threads[i] = new ThreadParallel(map);
}

并更改线程中的代码:

public class ThreadParallel implements Runnable{
    Map<Integer, String> map;
    Thread t;
    public ThreadParallel(Map<Integer, String> map) {
        this.map = map;
        t = new Thread(this);
        t.start();
    }
    @Override
    public void run() {    
        // adding data
    }

}

除非您在添加数据块时有一些同步,否则您可能会遇到比这更糟糕的问题。使用ConcurrentHashMap从不同线程同时使用,无需进一步同步(并且在监视器上没有任何阻塞)。

最新更新