zoukankan      html  css  js  c++  java
  • 对象锁的同步与异步

    同步:synchronized

      同步的概念就是共享 , 如果不是共享的资源 , 就没有必要进行同步。

    异步:asynchronized

      异步的概念就是独立 , 相互之间不受到任何制约。

    同步的目的就是为了线程安全 , 其实对于线程安全来说 , 需要满足两个特性:

    • 原子性 (同步):同步性就是一个事物要么一起成功,要么一起失败。
    • 可见性:就是一个线程的操作可以及时被其他线程感知到。
     1 package com.itdoc.multi.sync003;
     2 
     3 /**
     4  * 对象锁的同步与异步
     5  *
     6  * @author Wáng Chéng Dá
     7  * @create 2017-03-20 11:36
     8  */
     9 public class MyObject {
    10 
    11     public synchronized void method1() {
    12         try {
    13             System.out.println(Thread.currentThread().getName());
    14             Thread.sleep(5000);
    15         } catch (InterruptedException e) {
    16             e.printStackTrace();
    17         }
    18     }
    19 
    20     public synchronized void method2() {
    21 
    22         try {
    23             System.out.println(Thread.currentThread().getName());
    24             Thread.sleep(1000);
    25         } catch (InterruptedException e) {
    26             e.printStackTrace();
    27         }
    28     }
    29 
    30     public static void main(String[] args) {
    31         final MyObject mo = new MyObject();
    32 
    33         /**
    34          * 分析:
    35          * t1 线程先持有对象锁, t2 线程可以以异步的方式调用对象中的非 synchronized 修饰的方法。
    36          * t1 线程现持有对象锁, t2 线程若是要调用对象中的同步方法 (synchronized 修饰的方法),
    37          * 需要等 t1 线程之行结束将对象锁释放后才开始执行 (同步)。
    38          * 若是静态方法 .class 类锁, 效果一样。
    39          * 注意: 线程之间必须是相同的锁才可谈论异步同步问题。
    40          */
    41         Thread t1 = new Thread(new Runnable() {
    42             @Override
    43             public void run() {
    44                 mo.method1();
    45             }
    46         }, "T1");
    47 
    48         Thread t2 = new Thread(new Runnable() {
    49             @Override
    50             public void run() {
    51                 mo.method2();
    52             }
    53         }, "T2");
    54         t1.start();
    55         t2.start();
    56     }
    57 }

     脏读:

     1 package com.itdoc.multi.sync004;
     2 
     3 /**
     4  * 业务整体需要使用完整的 synchronized, 保持业务的原子性。
     5  *
     6  * @author Wáng Chéng Dá
     7  * @create 2017-03-20 13:52
     8  */
     9 public class DirtyRead {
    10 
    11     private String username = "z3";
    12 
    13     private String password = "123";
    14 
    15     public synchronized void setValue(String username, String password) {
    16         this.username = username;
    17         try {
    18             Thread.sleep(4000);
    19         } catch (InterruptedException e) {
    20             e.printStackTrace();
    21         }
    22         this.password = password;
    23         System.out.println("setValue 最终结果: username = " + username + " -- password = " + password);
    24     }
    25 
    26     public synchronized void getValue() {
    27         System.out.println("getValue 方法得到: username = " + this.username + " -- password = " + this.password);
    28     }
    29 
    30     public static void main(String[] args) throws InterruptedException {
    31         final DirtyRead dirtyRead = new DirtyRead();
    32         Thread t1 = new Thread(new Runnable() {
    33             @Override
    34             public void run() {
    35                 dirtyRead.setValue("z3", "456");
    36             }
    37         }, "T1");
    38         t1.start();
    39         Thread.sleep(1000);
    40         dirtyRead.getValue();
    41     }
    42 }

    若方法不同步 , 在 t1 线程执行睡眠时, 主线程已经执行完成 , 并打印出 getValue 方法得到: username = z3 -- password = 123 这种数据 , 只有方法同步 , 才能保持业务的原子性。

  • 相关阅读:
    C# 文件类的操作---删除
    C#实现Zip压缩解压实例
    UVALIVE 2431 Binary Stirling Numbers
    UVA 10570 meeting with aliens
    UVA 306 Cipher
    UVA 10994 Simple Addition
    UVA 696 How Many Knights
    UVA 10205 Stack 'em Up
    UVA 11125 Arrange Some Marbles
    UVA 10912 Simple Minded Hashing
  • 原文地址:https://www.cnblogs.com/chinda/p/6588097.html
Copyright © 2011-2022 走看看