Java同步块

Java同步块语法

编写同步块的一般语法如下。
这里的 lockObject 是对一个对象的引用,该对象的锁与同步语句表示的监视器相关联。

synchronized( lockObject ) 
{
   // 同步语句
}

内部工作原理

当一个线程想要在同步块内执行同步语句时,它必须在 lockObject的监视器上获取锁。
一次,只有一个线程可以获取锁对象的监视器。
所以所有其他线程必须等到这个线程,当前获取锁,完成它的执行。

这样,synchronized 关键字保证一次只有一个线程执行同步块语句,从而防止多个线程破坏块内的共享数据。

请记住,如果线程进入睡眠状态(使用 sleep()方法),那么它不会释放锁。
在这个休眠时间,没有线程会执行同步块语句。

如果'synchronized (lock)'中使用的锁对象为null,则Java 同步将抛出NullPointerException。

Java 同步块示例

请注意,printNumbers() 方法中的代码位于 synchronized 块中。

public class MathClass 
{
    void printNumbers(int n) throws InterruptedException 
    {
        synchronized (this) 
        {
            for (int i = 1; i <= n; i++) 
            {
                System.out.println(Thread.currentThread().getName() + " :: "+  i);
                Thread.sleep(500);
            }
        }
    }
}

我创建了两个线程,它们完全同时开始执行 printNumbers()方法。
由于块被同步,只允许一个线程访问,其他线程必须等到第一个线程完成。

public class Main 
{
    public static void main(String args[]) 
    {
        final MathClass mathClass = new MathClass();
        // 第一个线程
        Runnable r = new Runnable() 
        {
            public void run() 
            {
                try {
                    mathClass.printNumbers(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };

        new Thread(r, "ONE").start();
        new Thread(r, "TWO").start();
    }
}

输出:

ONE :: 1
ONE :: 2
ONE :: 3
TWO :: 1
TWO :: 2
TWO :: 3
https://onitroad.com 更多教程

Java同步方法

Java同步方法语法

编写同步方法的一般语法如下。
这里的 lockObject 是对一个对象的引用,该对象的锁与同步语句表示的监视器相关联。

<access modifier> synchronized method( parameters ) 
{
    // 同步代码
}

Java同步方法内部工作原理

与同步块类似,线程必须使用同步方法获取关联监视器对象上的锁。
在同步方法的情况下,锁对象是

  • '.class' 对象 - 如果方法是静态的。
  • 'this' 对象 - 如果该方法不是静态的。“this”指的是对调用同步方法的当前对象的引用。

Java synchronized 关键字本质上是可重入的,这意味着如果一个同步方法调用另一个需要相同锁的同步方法,那么当前持有锁的线程可以在不获取锁的情况下进入该方法。

Java同步方法示例

与同步块示例类似,我们可以在 printNumber()方法中应用 synchronized 关键字,它将使该方法成为同步的。
现在,如果我们再次运行该示例,我们将得到类似的输出。

public class MathClass 
{
    synchronized void printNumbers(int n) throws InterruptedException 
    {
        for (int i = 1; i <= n; i++) 
        {
            System.out.println(Thread.currentThread().getName() + " :: "+  i);
            Thread.sleep(500);
        }
    }
}

输出:

ONE :: 1
ONE :: 2
ONE :: 3
TWO :: 1
TWO :: 2
TWO :: 3
Java synchronized 关键字

Java synchronized 关键字将块或者方法标记为临界区。
临界区是一次只有一个线程正在执行的地方,并且该线程持有同步部分的锁。

synchronized 关键字有助于编写应用程序的并发部分,以保护此块中的共享资源。

synchronized关键字可用于

  • 一个代码块
  • 一个方法
日期:2020-09-17 00:09:58 来源:oir作者:oir