【问题标题】:Clarification needed for synchronized keyword需要对同步关键字进行说明
【发布时间】:2020-08-07 11:24:14
【问题描述】:

我正在学习 Java 中的多线程。我对线程如何使用 synchronized 关键字访问方法感到有些困惑,因为我正在寻找关于如何以及哪些线程可以访问它们的相互矛盾的教程。所以只是为了分享我目前的知识:

  • 我们创建的每个对象都有一个与之关联的监视器/锁
  • 任何时候线程访问同步方法时,都需要锁定它试图调用的对象/实例
  • 线程可以通过同步块中的 wait() 方法释放锁。
  • 一旦线程调用 notify/notifyAll,它就会唤醒调用 wait() 方法的线程。

所以我制作了一个虚拟程序来突出我好奇的东西,因为我在教程中得到了不同的答案(除非我没有正确理解它)..

主要:

public class Main {

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

    Operation operation = new Operation();

    Thread tOne = new Thread(new OperationProcessor(operation));
    Thread tTwo = new Thread(new OperationProcessor(operation));
    Thread tThree = new Thread(new OperationProcessor(operation));
    Thread tFour = new Thread(() -> {
        for(int i =0 ; i < 500; i ++){
            operation.subtract();
        }
    });

    tOne.start();
    tTwo.start();
    tThree.start();
    tFour.start();

    tOne.join();
    tTwo.join();
    tThree.join();

    System.out.println(operation.counter);
}
}

操作:

public class Operation {

int counter = 0;

public synchronized void add(){
    System.out.println(Thread.currentThread().getName() + " reading the value: " + counter);
    counter++; //same as counter = counter + 1;
}

public void subtract(){
    System.out.println(Thread.currentThread().getName() + " in the subtract method.");
}
}

运算处理器:

public class OperationProcessor implements Runnable {
private final Operation operation;

public OperationProcessor(Operation operation) {
    this.operation = operation;
}

@Override
public void run() {
    for (int i = 0; i < 1000; i++) {
        operation.add();
    }
}
}

我试图做的是测试不同的线程是否可以在同一时间调用其他非同步方法,因为其他线程在同一对象实例中调用其他同步方法?例如。如果 Thread1-3 依次调用 add() 方法(由于锁定),线程 4 是否可以在 Thread1-3 正在执行 add() 方法时调用减法()?但不确定我是否在这段代码中证明了这一点.. 而且如果 add() 和subtract() 方法都被同步了,这是否意味着只有一个线程可以访问对象中的所有同步方法?例如。线程A在add()方法中,线程B不能调用subtract()方法?

【问题讨论】:

    标签: java multithreading thread-safety


    【解决方案1】:

    如果线程 1-3 依次调用 add() 方法(由于锁),线程 4 是否可以在线程 1-3 正在执行 add() 方法时调用减法()?

    是的,可以。如果您让subtract 以某种方式修改counter,您可能会看到最终结果不是您所期望的。

    如果add() 和subtract() 方法都被同步了,这是否意味着只有一个线程可以访问对象中的所有同步方法?

    也是的。在这种情况下,对这两种方法的访问受到同一个锁的保护。如果一个线程因为正在执行add() 而持有锁,则另一个调用subtract() 的线程必须等待。

    例如线程A在add()方法中,线程B不能调用subtract()方法?

    它可以调用它,但它必须等到锁被释放才能运行方法中的任何代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 2011-07-14
      • 2011-04-11
      • 2016-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多