• synchronized 关键字


     关键字 synchronized 获取的锁都是对象锁 , 而不是把一段代码 (方法) 当作锁 , 代码中哪个线程先执行 synchronized 关键字修饰的方法 , 哪个线程就持有该方法所属对象的锁 , 两个对象获取的就是两个不同的锁 , 互不干扰。

    有一种情况则是相同的锁 , 即在静态方法上加 synchronized 关键字 , 表示锁定 .class 类 , 类一级别的锁 (独占 .class 类)。

     1 package com.itdoc.multi.sync002;
     2 
     3 /**
     4  * 关键字 synchronized 获取的锁都是对象锁, 而不是把一段代码 (方法) 当作锁,
     5  * 代码中哪个线程先执行 synchronized 关键字修饰的方法, 哪个线程就持有该方法所属对象的锁, 两个对象获取的就是两个不同的锁, 互不干扰。
     6  *
     7  * synchronized 关键字修饰静态方法, 标识锁定 .class 类, 类一级别的锁 (独占 .class 类)
     8  * @author Wáng Chéng Dá
     9  * @create 2017-03-20 8:24
    10  */
    11 public class MultiThread {
    12 
    13     private static int num = 0;
    14 
    15     public static synchronized void pointNum(String tag) {
    16         try {
    17             if ("a".equals(tag)) {
    18                 num = 100;
    19                 System.out.println(Thread.currentThread().getName() + " -->> tag is a , set num over!");
    20                 Thread.sleep(4000);
    21             } else {
    22                 num = 200;
    23                 System.out.println(Thread.currentThread().getName() + " -->> tag is b , set num over!" );
    24             }
    25             System.out.println(Thread.currentThread().getName() + " -->> tag : " + tag + ", num = " + num);
    26         } catch (InterruptedException e) {
    27             e.printStackTrace();
    28         }
    29     }
    30 
    31     public static void main(String[] args) {
    32 
    33         //创建两个不同的对象
    34         final MultiThread m1 = new MultiThread();
    35         final MultiThread m2 = new MultiThread();
    36 
    37         Thread t1 = new Thread(new Runnable() {
    38             @Override
    39             public void run() {
    40                 m1.pointNum("a");
    41 //                m2.pointNum("b");
    42             }
    43         }, "t1");
    44 
    45         Thread t2 = new Thread(new Runnable() {
    46             @Override
    47             public void run() {
    48 //                m1.pointNum("b");
    49                 m2.pointNum("b");
    50             }
    51         }, "t2");
    52         t1.start();
    53         t2.start();
    54     }
    55 }
      asynchronized synchronized static synchronized 分析
    相同线程相同对象

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t1 -->> tag is b , set num over!

    t1 -->> tag : b, num = 200

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t1 -->> tag is b , set num over!

    t1 -->> tag : b, num = 200

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t1 -->> tag is b , set num over!

    t1 -->> tag : b, num = 200

    按顺序执行,不存在相互干扰问题。
    相同线程不同对象

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t1 -->> tag is b , set num over!

    t1 -->> tag : b, num = 200

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t1 -->> tag is b , set num over!

    t1 -->> tag : b, num = 200

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t1 -->> tag is b , set num over!

    t1 -->> tag : b, num = 200

    按顺序执行,不存在相互干扰问题
    不同线程相同对象

    t1 -->> tag is a , set num over!

    t2 -->> tag is b , set num over!

    t2 -->> tag : b, num = 200

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 200

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t2 -->> tag is b , set num over!

    t2 -->> tag : b, num = 200

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t2 -->> tag is b , set num over!

    t2 -->> tag : b, num = 200

    不用 synchronized 修饰时,线程是不安全的,线程 t1 执行过程中,t2 线程也开始执行这段代码,在 t1 线程睡眠时,t2 线程执行完成将 num 值更改,所以 t1 线程也打印 t2 修改后的结果。添加修饰时,在 t1 线程完成释放锁后 t2 线程才开始执行。
    不同线程不同对象

    t1 -->> tag is a , set num over!

    t2 -->> tag is b , set num over!

    t2 -->> tag : b, num = 200

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t1 -->> tag is a , set num over!

    t2 -->> tag is b , set num over!

    t2 -->> tag : b, num = 200

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t1 -->> tag is a , set num over!

    ------------sleep 4 s-------------

    t1 -->> tag : a, num = 100

    t2 -->> tag is b , set num over!

    t2 -->> tag : b, num = 200

    无修饰和 synchronized 修饰时,不存在相互干扰问题,在 t1 线程执行当中,t2 线程也会执行,运行行为也是正常的。static synchronized 修饰时,只有t1线程执行完成释放锁之后 t2 线程才开始执行。这时候是类一级别的锁。
  • 相关阅读:
    2016年工作中遇到的问题11-20
    分布式服务框架Dubbo入门案例和项目源码
    分布式服务框架Dubbo入门案例和项目源码
    小米网抢购系统开发实践和我的个人观察
    小米网抢购系统开发实践和我的个人观察
    大学毕业4年-回顾和总结(8)-全局观-互联网项目研发-不在其位亦谋其政
    大学毕业4年-回顾和总结(8)-全局观-互联网项目研发-不在其位亦谋其政
    某电商项目的若干技术问题
    某电商项目的若干技术问题
    ZOJ 3861 Valid Pattern Lock
  • 原文地址:https://www.cnblogs.com/chinda/p/6586973.html
Copyright © 2020-2023  润新知