Java中Synchronized的用法

Laughing
2022-07-30 / 0 评论 / 949 阅读 / 搜一下 / 正在检测是否收录...
温馨提示:
本文最后更新于2024年03月15日,已超过388天没有更新,若内容或图片失效,请留言反馈。

Synchronized是Java中的关键字,是一种同步锁。他修饰的对象有以下几种。

  1. 修饰一个代码块

被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象。

  1. 修饰一个方法

被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象。

  1. 修饰一个静态方法

其作用的范围是整个静态方法,作用的对象是这个类的所有对象。

  1. 修饰一个类

其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

修饰一个代码块

当修饰一个代码块时,我们一定要记住,作用的对象是调用这个代码块的对象。我们下面通过一段代码看一下。

public class SynchronizedThread implements Runnable {

    /**
     * 计数
     */
    private static int count;

    @Override
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                count++;
                System.out.println(Thread.currentThread().getName() + ":" + count);
            }
        }
    }
}

这段代码很简单,就是对对类的一个静态变量进行计数。
接下来我们看一下调用这段代码的地方。

SynchronizedThread synchronizedThread = new SynchronizedThread();
Thread thread1 = new Thread(synchronizedThread,"Thread1");
Thread thread2 = new Thread(synchronizedThread,"Thread2");
thread1.start();
thread2.start();

运行上面的代码,查看控制台的输出信息

不论我们怎么运行,Thead1Thread2都是顺序执行的,这正是我们期望的。
接下来,我们对上面的代码稍微做一下改动,改动后如下

Thread thread3 = new Thread(new SynchronizedThread(),"Thread3");
Thread thread4 = new Thread(new SynchronizedThread(),"Thread4");
thread3.start();
thread4.start();

再次运行,查看控制台输出信息
可以看到Thead3Thread4不再是顺序执行。
why?Synchronized修饰一个代码块时,作用的对象是调用这个代码块的对象,我们可以看到Thead3Thread4中是new了一个新的对象,不再是同一个对象,所以Synchronized不再起作用。

修饰一个方法

修饰一个方法跟修饰一个代码块类似,只是作用域不同。
我们继续修改SynchronizedThread,修改后如下:

public class SynchronizedThread implements Runnable {

    /**
     * 计数
     */
    private static int count;

    @Override
    public void run() {
        increment();
    }

    public synchronized void increment(){
        for (int i = 0; i < 15; i++) {
            count++;
            System.out.println(Thread.currentThread().getName() + ":" + count);
        }
    }
}

再次调用上面的两次代码,会发现结果是一样的。

修饰静态方法

由于静态方法是属于类而不是属于对象,因此synchronized修饰的静态方法锁定的是这个类的所有对象。
我们再次对上面的SynchronizedThread进行修改,将increment()方法改成静态方法

public class SynchronizedThread implements Runnable {

    /**
     * 计数
     */
    private static int count;

    @Override
    public void run() {
        increment();
    }

    public synchronized static void increment(){
        for (int i = 0; i < 15; i++) {
            count++;
            System.out.println(Thread.currentThread().getName() + ":" + count);
        }
    }
}

我们再次通过以下代码进行调用

Thread thread3 = new Thread(new SynchronizedThread(),"Thread3");
Thread thread4 = new Thread(new SynchronizedThread(),"Thread4");
thread3.start();
thread4.start();

查看控制台,可以看到之前不是顺序执行的方法,现在也是按照线程顺序执行了

修饰一个类

我们再次对上面的SynchronizedThread进行修改

public class SynchronizedThread implements Runnable {

    /**
     * 计数
     */
    private static int count;

    @Override
    public void run() {
        increment();
    }

    public static void increment() {
        synchronized (SynchronizedThread.class) {
            for (int i = 0; i < 15; i++) {
                count++;
                System.out.println(Thread.currentThread().getName() + ":" + count);
            }
        }
    }
}

我们再次通过以下代码进行调用

Thread thread3 = new Thread(new SynchronizedThread(),"Thread3");
Thread thread4 = new Thread(new SynchronizedThread(),"Thread4");
thread3.start();
thread4.start();

查看控制台,现在也是按照线程顺序执行的。

0

评论 (0)

取消