如何使用线程访问相同的数据?

时间:2011-03-02 01:46:54

标签: java multithreading sockets network-programming client-server

我如何在客户端 - 服务器应用程序中执行此操作?

我想基本上让客户端通过不同的线程访问相同的数据,我想避免并发线程问题,所以我要求举例。

1 个答案:

答案 0 :(得分:2)

要访问同一条数据,您只需确保访问该类的同一实例。所以2个线程击中相同的单例,或者从某个工厂获得的同一个对象都将获得相同的数据。显然,具体情况取决于您的应用程序。

并发问题通常只会在修改某些数据时出现。比如说你有以下课程:

class Container {
  private List<?> data;

  public List<?> getData() {
    return this.data;
  }

  public void addData(Object data) {
    this.data.add(data);
  }
}

然后,这不一定是线程安全的。要使其线程安全,您需要锁定对象监视器。在这种情况下,可以通过以下两种方式之一完成此操作:

class Container {
  private List<?> data;

  public synchronized List<?> getData() {
    return this.data;
  }

  public synchronized void addData(Object data) {
    this.data.add(data);
  }
}

此解决方案将锁定对Container实例锁定的getData和setData的调用。这很好,除非你要向这个类添加第三个方法,它根本不使用数据,如果任何线程在getData或setData中,它也会被阻塞。为了更具体,你可以这样做:

class Container {
  private List<?> data;

  public List<?> getData() {
    synchronized (this.data) {
      return this.data;
    }
  }

  public void addData(Object data) {
    synchronized (this.data) {
      this.data.add(data);
    }
  }
}

然后使用数据变量对象锁。这样做的好处是,如果你添加第三个不使用数据的方法,那么调用getData或setData就不会阻止它。

这是Java并发安全的基本概述,希望它有所帮助。

请注意,问题的客户端 - 服务器性质并没有太大变化。如果您的线程是通过例如每个请求通过java servlet或某些东西创建的,那么这一切都以完全相同的方式应用。