synchronized 使用方法

断了今生、忘了曾经 提交于 2020-04-13 21:44:14

【今日推荐】:为什么一到面试就懵逼!>>>

概述

在java中synchronized是一个非常重要的关键字,它主要用来控制线程同步的,在多线程环境下能实现临界区资源的互斥访问。

synchronized关键字最主要有以下3种应用方式,下面分别介绍

  • 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁。
  • 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁。
  • 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
  • 修饰代码块,加锁对象为对象,则该类的所有的对象共享同一把锁。
1. 修饰实例方法
class SafeAdd implements Runnable {
    public static int num = 0;

    public synchronized void add() {
        num ++;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10000; ++i) {
            add();
        }
    }
}


public class SyncMethod {

    public static void main(String[] args) throws InterruptedException {
        SafeAdd safeAdd = new SafeAdd();
        Thread t1 = new Thread(safeAdd);
        Thread t2 = new Thread(safeAdd);

        t1.start();
        t2.start();

        t1.join();
        t2.join();
        System.out.println("SafeAdd: num = " + SafeAdd.num);
    }
}

运行结果:

SafeAdd: num = 20000

Process finished with exit code 0
2.修饰静态方法
class SafeAdd implements Runnable {
    public static int num = 0;

    public static synchronized void add() {
        num ++;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10000; ++i) {
            add();
        }
    }
}


public class SyncMethod {

    public static void main(String[] args) throws InterruptedException {
        SafeAdd safeAdd1 = new SafeAdd();
        SafeAdd safeAdd2 = new SafeAdd();
        Thread t1 = new Thread(safeAdd1);
        Thread t2 = new Thread(safeAdd2);

        t1.start();
        t2.start();

        t1.join();
        t2.join();
        System.out.println("SafeAdd: num = " + SafeAdd.num);
    }
}

运行结果:

SafeAdd: num = 20000

Process finished with exit code 0
3. 同步代码块
class SafeAdd implements Runnable {
    public static int num = 0;

    @Override
    public void run() {
        synchronized (this) {
            for (int i = 0; i < 10000; ++i) {
                num ++;
            }
        }
    }
}


public class SyncMethod {

    public static void main(String[] args) throws InterruptedException {
        SafeAdd safeAdd = new SafeAdd();
        Thread t1 = new Thread(safeAdd);
        Thread t2 = new Thread(safeAdd);

        t1.start();
        t2.start();

        t1.join();
        t2.join();
        System.out.println("SafeAdd: num = " + SafeAdd.num);
    }
}

运行结果:

SafeAdd: num = 20000

Process finished with exit code 0
4. 同步代码块,加锁对象为Class对象
class SafeAdd implements Runnable {
    public static int num = 0;

    public static void add() {
        num ++;
    }

    @Override
    public void run() {
        synchronized (SafeAdd.class) {
            for (int i = 0; i < 10000; ++i) {
                add();
            }
        }
    }
}

public class SyncMethod {
    public static void main(String[] args) throws InterruptedException {
        SafeAdd safeAdd1 = new SafeAdd();
        SafeAdd safeAdd2 = new SafeAdd();
        Thread t1 = new Thread(safeAdd1);
        Thread t2 = new Thread(safeAdd2);

        t1.start();
        t2.start();

        t1.join();
        t2.join();
        System.out.println("SafeAdd: num = " + SafeAdd.num);
    }
}

运行结果:

SafeAdd: num = 20000

Process finished with exit code 0
总结
  1. synchronized的作用对象是实例方法和普通对象时,则多个线程仅共同争抢该对象的锁。
  2. synchronized的作用对象是静态方法或一个类时,则该类所有的对象共享一个锁。
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!