代码之家  ›  专栏  ›  技术社区  ›  Cratylus

Java同步块

  •  4
  • Cratylus  · 技术社区  · 15 年前

    public void doSomething(){
        synchronized(this){
            //some code processing here
        }
        String temp = "init"; //instead of i++
        synchronized(this){
            //some other code processing here
        }
    }
    

    这个方法等同于 public synchronized void doSomething() ?

    有什么原因吗 假设某些执行中的线程调度程序 有效地实现与同步整个功能相同的流程?即:

    • 螺纹1 进入第一个同步块。
    • 阻碍。
    • 继续 i++ 移动到第二个同步块 仍然被封锁。
    • 因此, 螺纹1 已退出两个同步块。

    我只想知道:

    • 我能指望两个线程都支持的所有执行上下文吗( 螺纹1 )可以同时在方法中吗?例如, 螺纹2 在第一个同步块中 螺纹1 在第二个同步块中实现并发。
    • 是否会有一些执行流,其中方法中(一次)只有一个线程,从而有效地序列化整个流,使其等效于 公共剂量测量() ?
    6 回复  |  直到 12 年前
        1
  •  11
  •   Jon Skeet    15 年前

    一些 全部的 处决。

    实际上,另一个线程有可能在执行的中途获取锁(无论是对于这个方法还是同一个监视器上的其他代码锁)。如果方法本身是同步的,就不会发生这种情况,因此它们不是等价的。

    (作为旁白,锁定 this

    编辑:要响应您的编辑:

    依赖于所有执行上下文 两个螺纹(例如螺纹1和 Thread2)可以在 同时,例如第一个 同步块和线程1 同步块实现并发

    绝对不是!我保证你 不会

    一次可以在非同步部分执行任意数量的线程。对于任何一个实例(因为您正在 )只能执行一个线程 同步块的。如果要实现并发,就必须在不同的监视器上进行同步。

    此外,听起来您希望调度器保证在等待锁时让另一个线程获取锁。我不相信有任何这样的保证-一个线程执行第一个块可以释放锁,但继续在同一时间片,并重新获得它之前,任何其他线程进入。在某些jvm中,这种情况可能不会发生,但我不相信有任何保证。

        2
  •  3
  •   Toby    15 年前

    不,不是。例如上面的代码

    线程1进入第一个sync'd块并执行它,然后退出。 线程2进入第一个sync'd块执行它,然后在被关闭之前进入第二个sync'd块。 线程1现在无法继续,直到线程2退出第二个同步块。

        3
  •  3
  •   Tim Bender    15 年前

    我需要知道的是,我是否可以依赖两个线程(例如Thread1和Thread2)可以同时在方法中的所有执行上下文,例如第一个sync块中的Thread2和第二个sync块中的Thread1来实现并发

    this . 由于对两个同步块使用相同的锁,Thread2不可能位于第一个块中 synchronized 如果Thread1位于第二个 已同步

        4
  •  2
  •   Vineet Reynolds    15 年前

    假设synchronized关键字用于在Java中实现监视器,则不能保证给定的代码段是同步的。

    实际上,两个线程是否都可以完成第一个同步块,然后执行语句以增加 i

    我假设变量

    sample chapter from Inside the Java Virtual Machine

    编辑 :

    考虑到这个问题现在反映了本地字符串对象的使用,操作序列可以被认为是线程安全的。每个线程在堆栈上创建自己对String对象的本地引用;一个线程中对象的任何变异都不会影响另一个线程,因为字符串对象的属性是不可变的(当发生变异时,会为所有实际目的创建一个新的字符串对象,因此状态不会在线程之间真正共享)。

    强调 :

    在尝试线程同步时,如果对共享数据的访问是互斥的,则认为操作序列是线程安全的;这样一来,一个线程将无法读取或写入共享变量,而另一个线程正在执行涉及共享数据的操作。只使用局部变量,消除了线程之间的共享感。

        5
  •  1
  •   Nate W.    15 年前

    synchronized void doSomething() 因为 i++

    int temp = i; i = i + 1; result = temp

    如果这些操作不是原子化的,那么 i

        6
  •  0
  •   Gopi    15 年前

    此方法与使其成为同步方法不同。