Java 在对象上同步

标签 java methods locking synchronize

如何同步来自同一个类的两个不同方法以锁定同一个对象?这是一个例子:

public class MyClass extends Thread implements Observer{
  public List<AnotherClass> myList = null;
  
  public MyClass(List<AnotherClass> myList){
    this.myList = myList;
  }
  
  public void run(){
    while(true){
       //Do some stuff 
       myList.add(NotImportantElement);
    }
  }

  public void doJob{
    for(int i=0; i<myList.size; i++){
      ElementClass x = myList.get(i);
      //Do some more stuff
    }
  }
}

问题是在执行 doJob 时如何阻止 run() 访问 myList,反之亦然?

想象一下:我启动线程并开始向我的列表中添加元素。在一个随机的时刻,我从另一个保存对我的线程的引用的类调用 doJob()。

我应该怎么做锁?谢谢!

L.E.

好了,我明白了锁的概念,但是现在我还有一个问题。

假设我有一个带有public static myList 的类并且只有该类的一个 实例。从那个实例开始,我创建了 nThread 实例,它获取该列表的每个元素并用它做一些事情。

现在,在特定时刻,myList 被更新。那些已经在处理 myList 元素的线程会发生什么?我应该如何在更新 myList 时锁定访问权限?

最佳答案

注意:此代码假定您只有一个 MyClass 实例。根据您的帖子,听起来是这样。

public class MyClass extends Thread implements Observer{
  private List<AnotherClass> myList = null;
  private Object lock = new Object();

  public MyClass(List<AnotherClass> myList){
    this.myList = new ArrayList(myList);
  }

  public void run(){
    while(true){
       //Do some stuff 
       synchronized(lock) {
        myList.add(NotImportantElement);
       }
    }
  }

  public void doJob{
    synchronized(lock) {
      for(int i=0; i<myList.size; i++){
        ElementClass x = myList.get(i);
        //Do some more stuff
      }
    }
  }
}

编辑:添加了制作列表的副本,以便外部实体无法根据 JB Nizet 更改列表

编辑 2: 将变量设为私有(private),以便其他人无法访问它们

关于Java 在对象上同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7851604/

相关文章:

python - 关于Python线程Lock对象

java - 在 Antlr 3 中生成自定义 JavaDoc

java - 在正在运行的 Spark Streaming 作业中动态修改窗口长度或创建多个窗口

Java,数组的setter方法。两类

ruby - 如何使用 capitalize 方法将字符串数组中的第一个字母大写?

c++ - 类方法会增加类实例的大小吗?

c# - 在异步方法中根据 Id 锁定

sql-server - 显式锁定 SQL Server 中的表?

java - 在标签中显示带有图像图标的井字棋盘

java - 从 TextField 使用 JavaFX KeyTyped 事件