在线程之间共享只读引用

时间:2012-04-19 22:46:11

标签: java multithreading reference

假设我们有2个线程,线程A和线程B.

线程A是主要方法,包含大型数据结构。

是否可以创建第二个线程并将数据结构的地址(指针)(线程A的本地)传递给线程B,这样两个线程都可以从数据结构中读取?

这一点是为了避免在线程B上复制整个数据结构或花费大量时间从数据结构中提取相关信息以供线程B使用

请记住,两个线程都没有修改数据

5 个答案:

答案 0 :(得分:3)

  1. 在Java中,不使用术语指针,而是参考。
  2. 可以将其作为任何其他对象传递给另一个线程。 与Java中的任何(非最终)类一样,您可以扩展它,添加成员,添加构造函数等。
  3. (如果需要修改数据)您需要确保没有并发问题。

答案 1 :(得分:1)

它在java中被称为引用,因为您无法直接访问传统意义上的指针。 (对于大多数情况,考虑它是“安全的”,因为每个引用都是一个总是按值传递的指针,唯一合法的操作就是取消引用它。 NOT 与C ++相同'参考。')

您当然可以在线程之间共享引用。任何可以获取对它的引用的线程都可以看到并使用堆上的任何内容。您可以将其放在静态位置,也可以将Runnable上的参考值设置为指向数据。

public class SharedDataTest {

  private static class SomeWork implements Runnable {
    private Map<String, String> dataTable;

    public SomeWork(Map<String, String> dataTable) {
      this.dataTable = dataTable;
    }

    @Override
    public void run() {
      //do some stuff with dataTable
    }
  }

  public static void main(String[] args) {

    Map<String, String> dataTable = new ConcurrentHashMap<String, String>();

    Runnable work1 = new SomeWork(dataTable);
    Runnable work2 = new SomeWork(dataTable);

    new Thread(work1).start();
    new Thread(work2).start();

  }

}

答案 2 :(得分:1)

是的,这是可能的并且是常见的事情,但您需要确保使用正确的同步以确保两个线程都能看到数据的最新版本。

答案 3 :(得分:0)

共享对不可变对象的引用是安全的。粗略地说,不可变对象是在构造之后不会改变其状态的对象。语义不可变对象应该只包含最终字段,而这些字段又引用不可变对象。

如果要共享对可变对象的引用,则需要使用正确的同步,例如使用synchronized或volatile关键字。

安全地共享数据的简单方法是使用java.util.concurrent包中的实用程序,例如 AtomicReference 或ConcurrentHashMap,但是如果您共享的对象是可变的,您仍然必须非常小心。 / p>

答案 4 :(得分:0)

如果您没有对共享数据进行任何修改,则可以使用共享引用,并且不会产生显着的开销。

但是,当您开始同时开始修改共享对象时要小心,在这种情况下,您可以使用java中提供的数据结构(请参阅Collections中的实例工厂方法),或者使用自定义同步方案,例如与java.util.concurrent.locks.ReentrantLock