我只是好奇,有没有可能一个线程T1部分执行了一个同步块,然后释放了对象上的锁,而另一个线程T2执行了同一个同步块?大概是这样的:
line1: synchronized(this){
line2: if(INSTANCE == null)
line3: INSTANCE = new Object(); //say a variable is initialized
line4: return INSTANCE;
line5: }
线程T1是否可能获取当前对象的锁(<code>this</code>)并执行第1行和第2行。然后线程T1被线程T2抢占,T1释放锁,T2获取<code>this</code<的锁并执行相同的块(所有第1行到第5行)。然后线程T1再次获取锁并从第3行继续执行?
基本上,T1会将INSTANCE
视为null,T2也是如此,每个都会创建一个新的Object。
如果这是不可能的,有人能解释为什么不可能吗?
补遗:
谢谢大家的回答。我的问题有点误导。我真正想问的是,有没有可能一旦一个线程正在执行一个同步的块,它就可以在整个块被执行之前释放锁(不是通过显式调用< code>wait()而是依赖于进程和CPU的某种方式)?在JLS或JVM中是否有一个契约保证一旦一个线程开始执行一个同步块,对象上的锁直到该块结束才会被释放?我的理解是同步保证没有两个线程可以同时执行这个块(或者其他同步的方法/块),但是锁会一直保持到到达块的末尾?这是显而易见的,但是在JLS中有规定吗?
我很确定在第一个线程执行完整个块之前,第二个线程不可能进入< code>synchronize块。一旦获得对象的锁,所有其他试图进入同步代码的线程都将被阻塞。
请点击此处查看更多信息:http://tutorials . jen kov . com/Java-concurrency/synchronized . html
即使线程被抢占,它也不会释放锁。锁仍被锁住。如果另一个线程出现,它将阻塞(停止运行)直到释放锁,即使原始线程在释放锁之前多次被抢占。基本上,几乎任何类型的锁都在堆中有一些存储,这些存储被写入以指示存在锁。它是永久的,直到线程或系统写入一个不同的值来指示锁是空闲的。
当然,编写允许访问实例或字段的代码而不需要锁是可能的,但这是一个编码错误。原始线程也有可能提前退出块(比如抛出异常)——这会释放锁,其他线程可以正常继续。
线程抢占不会导致被抢占的线程释放其锁。如果是这样,锁将一文不值。同步块的全部意义在于,它将禁止其他线程在同一对象上同步,直到线程释放锁(通过离开
同步
块)。
问题内容: 我正在查看包含同步方法的第三方库中的一些代码,在此方法中,有一个锁定在实例变量上的同步块。与此类似: 这有意义吗?如果是这样,在同步方法中使用同步语句有什么好处? 鉴于同步方法锁定了整个对象,对我来说似乎是多余的。在使用非私有的实例变量时,这种方法是否有意义? 问题答案: 在您的示例中,该方法 同时 锁定了和的实例。其他方法可能仅锁定对象的实例 或 对象。 因此,是的,这完全取决于他们
下面是
主要内容:1 什么是Java同步代码块,2 Java同步代码块的要点,3 Java同步代码块的语法,4 Java同步代码块的例子1,5 Java同步代码块的例子21 什么是Java同步代码块 同步代码块可用于对方法的任何特定资源执行同步。 假设您的方法中有50行代码,但是您只想同步5行,则可以使用synchronized代码块。 如果将方法的所有代码放在同步代码块中,它的效果与同步方法相同。 2 Java同步代码块的要点 同步代码块用于锁定任何共享资源的对象。 同步代码块的范围小于该方法。 3
问题内容: 我在Heinz Kabutz的 Java专家 通讯版本中看到了这一点,尽管Kabutz博士的文章的其余部分(乃至全部)都得到了很好的解释和详细说明,但他似乎掩盖了这段代码的作用,或更重要的是,它的意义是: 嵌套块的含义是什么?这如何影响尝试执行的不同线程? 问题答案: 有两个可能需要注意的问题 如果使用等待/通知,嵌套锁很容易导致死锁。这是为什么的解释。http://tutorials
我正在寻找有关同步块的澄清。考虑一下这个类 - A是单例。getValue在整个应用程序中被多个线程大量访问。我添加了一个新方法remove,它从映射中删除一个键。如果如上所述执行删除, 当线程位于remove方法的同步块中时,我假设它将获取map对象上的锁。这是否意味着其他试图通过getValue方法访问映射的线程将被阻止?(我希望他们这样做。) 当remove方法的同步块中没有线程时,访问ge
问题内容: 如果我在同步块内创建一个新线程,该块是否将保持锁定状态,直到线程执行完成为止?如果没有,那么直到什么时候才能保持锁定状态? 问题答案: 如果代码d具有新创建的线程,则它将保持锁定,从而等待它完成。由于没有锁,因此在调用完成后将不释放锁定。