【问题标题】:Edit main thread object by child threads in java在java中通过子线程编辑主线程对象
【发布时间】:2013-06-25 10:11:48
【问题描述】:

我有一个主线程,我在其中定义了一个 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
}

}

【问题讨论】:

  • 在构造函数中使用this 可能很危险,因为此时对象尚未完全构造。
  • 您应该发布更多代码,因为从您提供的代码中不清楚如何创建多个地图。

标签: java multithreading shared-objects


【解决方案1】:

不是最好的设计,但是如何在主类中将地图设为公共和静态并在线程类中访问它。同时使用 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");
} 

}

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      我真的不认为线程正在制作本地副本,碰巧 HashMap 不是线程安全的,尝试用 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap) 替换 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
          }
      

      }

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-27
          • 2020-02-26
          • 1970-01-01
          • 2011-11-01
          • 1970-01-01
          • 2011-01-25
          相关资源
          最近更新 更多