【问题标题】:synchronized statements with "break"带有“break”的同步语句
【发布时间】:2017-06-02 10:53:04
【问题描述】:

我在我的编解码器中使用了同步语句,并且块中有一个“中断”:

for (int j = 0; j < testPathSize; j++) {

  synchronized (lock) {
    if (kpis.get(j).getDate() > startTimeInMs) {

      if (j > 0) {
        if ((kpis.get(j).getDate() - startTimeInMs)
            > (startTimeInMs - kpis.get(j - 1).getDate())) initTestPath = j - 1;
        else initTestPath = j;
      } else initTestPath = j;

      break;
    }
  }
}

我想知道break什么时候执行,“锁”会被释放?

谢谢。

【问题讨论】:

  • 请发布更多代码,因为我们无法引用您发布的 sn-p,因为它太小了 - 例如。同步块内的 while/break 不会释放锁。
  • 您应该尝试设计您的代码,使任何线程都不需要持有锁的时间超过更新一些变量所需的时间。 Google 的“乐观锁定”可以找到一些示例,说明即使在可能发生冲突的操作序列很长的情况下也能实现这一目标。

标签: java multithreading break synchronized


【解决方案1】:

只要执行超出synchronized 块的范围,就会释放锁。不管是因为正常的程序流程、break、异常还是任何其他方式超出了块。

有关其工作原理的官方规范可以在 Java 语言规范的 14.19 The synchronized Statement 段中找到。

【讨论】:

  • 谢谢!我明白了!
【解决方案2】:

这取决于break 将您的代码带到哪里:

  • 如果break 结束的循环完全包含在synchronized 块中,则break 不会释放锁,例如:

    synchronized (thing) {
        for (;;) {
            break;
        }
    }
    
  • 否则,执行将离开synchronized区域,释放锁,例如:

    for (;;) {
        synchronized (thing) {
            break;
        }
    }
    

规则是当你出于任何原因退出synchronized块时,锁被释放,或者在锁对象上调用wait

编辑:synchronized 块在循环内时,您的代码属于第二类。所以break会释放锁。

【讨论】:

  • 你和我的观点基本相同(但更好)。如果我编辑我的代码 sn-ps 并删除我的答案,好吗?
【解决方案3】:

java 文档说

同步语句(第 14.19 节)计算对对象的引用;然后它会尝试在该对象的监视器上执行锁定操作,并且在锁定操作成功完成之前不会继续进行。执行完锁定操作后,将执行同步语句的主体。如果主体的执行完成,无论是正常的还是突然的,都会在同一个监视器上自动执行解锁操作。

同步方法(第 8.4.3.6 节)在调用时自动执行锁定操作;在锁定操作成功完成之前,它的主体不会被执行。如果该方法是一个实例方法,它会锁定与调用它的实例相关联的监视器(即,在方法体执行期间将被称为 this 的对象)。如果该方法是静态的,它会锁定与 Class 对象关联的监视器,该对象表示定义该方法的类。如果方法主体的执行完成,无论是正常的还是突然的,都会在同一个监视器上自动执行解锁操作。

意味着同步块以任何java方式退出正常或突然锁将被放弃。在这里休息;是正常的退出方式。

请参阅下面的示例。

public class LockAndBreak {
private static final Object lock = new Object();

public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 3; i++) {
        new Thread1("Thread : " + i, lock).start();
        Thread.sleep(2000);
    }
}}

class Thread1 extends Thread {
private Object lock;

public Thread1(String name, Object lock) {
    super(name);
    this.lock = lock;
}

@Override
public void run() {
    System.out.println("Running Thread " + this.getName());
    int i = 0;
    synchronized (lock) {
        while (true) {
            System.out.println("Printing from thread " + this.getName() + "-->" + i);
            i++;
            if (i > 9) {
                System.out.println("Existing the thread : " + this.getName());
                break;
            }
        }
    }
}}

【讨论】:

    猜你喜欢
    • 2017-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 2020-09-06
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多