zoukankan      html  css  js  c++  java
  • 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 线程才开始执行。这时候是类一级别的锁。
  • 相关阅读:
    [bbk5177]第62集第6章 用scheduler自动化 10(章节标题内容调整)
    [bbk4956]第65集 第7章 数据库的维护 02
    [bbk4940]第61集第6章 用scheduler自动化 09
    [bbk5179]第66集 第7章 数据库的维护 03
    ORA01031: insufficient privileges(有待于二次解决)
    Google Analytics功能篇 如何跟踪邮件打开率与点击率
    小资之豆浆篇 (IS2120@BG57IV3)
    wix custom action 之 vbscript 简明步骤(IS2120@BG57IV3)
    c++ faq (15)
    linux 下面字符串处理函数实现 抄来看一下 抄自[http://blog.csdn.net/BeWithLei/article/details/1719242]
  • 原文地址:https://www.cnblogs.com/chinda/p/6586973.html
Copyright © 2011-2022 走看看