Allbet Gaming

联博api:今后不怕Synchronized锁

admin 2020年08月21日 科技 57 2
  • Synchronized的使用

​ Synchronized是通过监视器保证线程同步从而保证线程平安。然则Synchronized锁可以锁工具和锁类,并会发生差别的效果,通过下面的案例彻底明白Synchronized锁的使用方式。

即:

对于通俗的同步方式,锁是当前实例工具

对于静态同步方式,锁是该类

对于同步方式块,锁是Synchronized括号内里设置的工具。

下面通过代码具体剖析几种情形。要想领会并发情形,首先我们必须知道,类信息、实例工具划分存放在什么位置。类的信息,包罗静态变量都是存放在方式区中;而实例工具,包罗类的成员变量,是存放在堆中。

1. 成员变量+通俗同步方式+锁

public class SynDemo implements Runnable {

    private int sum = 0;

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

    public synchronized void add() {
        for (int i = 0; i < 1000; i++) {
            sum++;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync01);
        thread1.start();
        thread2.start();
        thread1.join();		//守候线程执行完
        thread2.join();		//守候线程执行完
        System.out.println(sync01.sum);
        System.out.println(new SynDemo().sum);
    }
}

result:
	2000
        0
public class SynDemo implements Runnable {

    private int sum = 0;

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

    public synchronized void add() {
        for (int i = 0; i < 1000; i++) {
            sum++;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        SynDemo sync02 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync02);
        thread1.start();
        thread2.start();
        thread1.join();		//守候线程执行完
        thread2.join();		//守候线程执行完
        System.out.println(sync01.sum);
        System.out.println(sync02.sum);
    }
}

result:
	1000
        1000
        0

剖析:

​ 明白了这两个demo再去明白同步代码块下的多线程平安问题,将会到达事半功倍的效果。上面两个demo主要是想表达,成员变量和类的实例化工具一样,都是在堆中建立,每次new工具,都会在堆中发生一个新的工具。以是第一个demo中,当在线程同步的情形下,两个线程去操作统一个工具,最后的效果是2000;而第二个demo中,两个线程去操作两个实例化工具,以是每个工具的成员变量sum为1000。因此我们也可以发现,其实在第一个demo中才会有线程平安问题,在第二个demo中是不存在线程平安问题的,有疑问可以去掉锁验证一下。通过这个例子也可以去明白为什么sping中多例是线程平安的。

2. 成员变量+同步代码块+工具锁

public class SynDemo implements Runnable {

    private int sum = 0;

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

    private void add() {
        synchronized (this) {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync01);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sync01.sum);
        System.out.println(new SynDemo().sum);
    }
}

result:
	2000
        0
public class SynDemo implements Runnable {

    private int sum = 0;

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

    private void add() {
        synchronized (this) {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        SynDemo sync02 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync02);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sync01.sum);
        System.out.println(sync02.sum);
        System.out.println(new SynDemo().sum);
    }
}

result:
	1000
	1000
	0

剖析:

​ 同案例1一样,Demo1为两个线程执行一个实例化工具,然则加了Synchronized工具锁,因此实现了同步,保证线程平安。Demo2为两个线程执行两个实例化工具,各自行使各自的成员变量sum,因此不会发生并发平安问题。

3. 成员变量+同步代码块+类锁

public class SynDemo implements Runnable {

    private int sum = 0;

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

    private void add() {
        synchronized (SynDemo.class) {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync01);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sync01.sum);
        System.out.println(new SynDemo().sum);
    }
}

result:
	2000
	0
public class SynDemo implements Runnable {

    private int sum = 0;

    @Override
    public void run() {

        add();
    }

    private void add() {
        synchronized (SynDemo.class) {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        SynDemo sync02 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync02);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sync01.sum);
        System.out.println(sync02.sum);
        System.out.println(new SynDemo().sum);
    }
}

result:
	1000
	1000
	0

剖析:

​ Demo1为两个线程执行一个实例化工具,会发生并发平安问题,然则加了同步类锁(可以明白为锁的级别比工具锁更高),固然也可以实现并发同步,保证线程平安。而Demo2同样实例化两个工具,各自操作各自的成员变量sum,也不会发生线程平安问题。

4. 静态变量+通俗方式+锁

public class SynDemo implements Runnable {

    private static int sum = 0;

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

    private synchronized void add() {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync01);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sum);
    }
}

result:
	2000
public class SynDemo implements Runnable {

    private static int sum = 0;

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

    private synchronized void add() {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        SynDemo sync02 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync02);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sum);
    }
}

输出效果不确定(存在线程平安问题)

剖析:

​ 从案例4我们要注意,由成员变量换成静态变量,而上面已经讲过,静态变量存放在方式区中,所有实例化工具共享一份。再看Demo1,两个线程执行统一个实例化工具,然后添加的是工具锁,因此该工具锁能锁住该实例化工具,实现同步,保证线程平安。

​ Demo2是两个线程执行两个实例化工具,添加的是工具锁,相当于各自的工具锁锁住各自的工具,而静态变量是类变量,存放在方式区中而不是堆中,此情形工具锁并不能保证线程同步,因此会发生线程平安问题。

5. 静态变量+静态方式+锁

public class SynDemo implements Runnable {

    private static int sum = 0;

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

    static synchronized void add() {
        for (int i = 0; i < 1000; i++) {
            sum++;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync01);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sum);
    }
}

result:
	2000
public class SynDemo implements Runnable {

    private static int sum = 0;

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

    static synchronized void add() {
        for (int i = 0; i < 1000; i++) {
            sum++;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        SynDemo sync02 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync02);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sum);
    }
}

result:
	2000

剖析:

​ 该案例相比案例4,锁由工具锁换成类锁,对于Demo1,两个线程操作一个工具,毫无疑问会使其同步。而Demo2,两个线程执行两个实例化工具,由于使用的是类锁,也会使线程同步,保证线程平安。

6. 静态变量+同步代码块+工具锁

public class SynDemo implements Runnable {

    private static int sum = 0;

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

    private void add() {
        synchronized (this) {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync01);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sum);
    }
}

result:
	2000
public class SynDemo implements Runnable {

    private static int sum = 0;

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

    private void add() {
        synchronized (this) {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        SynDemo sync02 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync02);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sum);
    }
}

输出效果不确定(存在线程平安问题)

剖析:该案例和案例4一样,添加工具锁,只能保证统一工具的并发同步,不能保证差别工具同步。

7. 静态变量+同步代码块+类锁

public class SynDemo implements Runnable {

    private static int sum = 0;

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

    private void add() {
        synchronized (SynDemo.class) {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync01);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sum);
    }
}

result:
	2000
public class SynDemo implements Runnable {

    private static int sum = 0;

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

    private void add() {
        synchronized (SynDemo.class) {
            for (int i = 0; i < 1000; i++) {
                sum++;
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        SynDemo sync01 = new SynDemo();
        SynDemo sync02 = new SynDemo();
        Thread thread1 = new Thread(sync01);
        Thread thread2 = new Thread(sync02);
        thread1.start();
        thread2.start();
        thread1.join();  //守候线程执行完
        thread2.join();  //守候线程执行完
        System.out.println(sum);
    }
}

result:
	2000

剖析:

​ 该案例同案例5一样,添加类锁,无论是多个线程操作一个实例化工具照样多个实例化工具,都能保证线程平安。

总结:

工具锁只能保证各自实例化工具并发的线程平安问题。类锁可以保证多个实例化多谢的平安问题

,

px111.net

欢迎进入平心在线官网(原诚信在线、阳光在线)。平心在线官网www.px111.net开放平心在线会员登录网址、平心在线代理后台网址、平心在线APP下载、平心在线电脑客户端下载、平心在线企业邮局等业务。

Allbet Gaming声明:该文看法仅代表作者自己,与阳光在线无关。转载请注明:联博api:今后不怕Synchronized锁
发布评论

分享到:

allbet登陆网址:飞鹤中期多赚57% 每股派0.1375元
2 条回复
  1. Allbet注册
    Allbet注册
    (2020-08-11 00:10:35) 1#

    欧博亚洲网址欢迎进入欧博亚洲网址(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。不解释,上车

  2. UG环球官方网
    UG环球官方网
    (2020-08-21 00:45:31) 2#

    欧博亚洲官网开户网址欢迎进入欧博亚洲官网开户网址(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。不错一直在看。

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。