首页 > 解决方案 > 没有静态引用的 Java Runnable

问题描述

我正在尝试使用可运行接口学习多线程,但在弄清楚如何传递信息时遇到了一些麻烦。基本上,在下面的示例中,我想从 Hashmap 中删除静态引用,但如果我这样做,程序就会中断。如何在不使用 static 关键字的情况下将 hashmap 传递给可运行接口类?

public class ThreadDemo {

static HashMap <String, Integer>map = new HashMap<>();

public String Hi() {
    return "hi";
}

public String Hello() {
    return "Hello";
}

public void addToMap(String item) {
    if (map.containsKey(item)) {
        map.put(item, map.get(item) + 1);
    } else {
        map.put(item, 1);
    }
}


public static void main(String[] args) throws InterruptedException {

    ArrayList<Thread> all = new ArrayList<>();
    
    for (int i = 0; i < 50; ++i) {
        threader threader = new threader();
        all.add(new Thread(threader));
    }

    for (Thread thread : all) {
        thread.start();
    }
    
    for (Thread thread : all) {
        thread.join();
    }
    
    ThreadDemo td = new ThreadDemo();
    System.out.println(td.map);

    
}

}

还有一个实现 Runnable 的类

public class threader implements Runnable {

ThreadDemo td = new ThreadDemo();

@Override
public void run() {
    
    synchronized(td.map) {
        td.addToMap(td.Hi());
        td.addToMap(td.Hello());

    }
    
    
}

}

标签: javamultithreadingrunnable

解决方案


类实例都是关于信息的。

public class threader implements Runnable {
   final private ThreadDemo td;

   public threader(ThreadDemo td) {
      this.td = td;
   }

   @Override
   public void run() {
     ..
   }

}

然后使用(细节省略,只是想法):

ThreadDemo theTd = new ThreadDemo();
for (...) {
    threader threader = new threader(theTd);
    all.add(new Thread(threader));
}

....

当然,所有线程都使用相同的 ThreadDemo,具有相同的映射,因此您需要确保以某种方式互锁访问,例如,通过使用synchronized. 在这个ThreadDemo.addToMap例子中,方法应该是同步的,而不是addToMap. 这将“维护地图”的责任放在了实际拥有地图的地方,因此是一个更好的设计。

我选择共享 ThreadDemo 而不仅仅是 ThreadDemo 中的地图,因为在我看来 ThreadDemo 的意图只是成为地图的包装。


推荐阅读