zoukankan      html  css  js  c++  java
  • 同步解决线程安全问题的三种实现

    同步解决线程安全问题的三种实现

    /*
     * 同步可以解决安全问题的根本原因就在那个对象上。
     * 
     * A:同步代码块的格式及其锁对象问题?
     *         格式:
     *         synchronized (对象名称) {
     *             需要同步的代码;
     *         }
     * 
     *         同步代码块的锁对象是谁呢?
     *             任意对象。
     * 
     * B:同步方法的格式及其锁对象问题?
     *         如果一个方法一进去就看到了代码被同步了,那么我就在想能不能把这个同步加在方法上呢? 答:能。
     *         把同步关键字加在方法上。
     *         格式:
     *         synchronized private void sellTicket() {...}
     *         private synchronized void sellTicket() {...}    // 习惯上这样写
     * 
     *         同步方法的锁对象是谁呢?(方法的内部有一个你看不到的对象是this啊,傻瓜哈)
     *             this
     * 
     * C:静态同步方法的格式及其锁对象问题?
     *         格式:
     *         private static synchronized void sellTicket() {...}
     *         
     *         静态同步方法的锁对象是谁呢?
     *             当前类的字节码文件对象。(反射会讲)
     * 
     *         类的初始化过程:Person p = new Person(); // 第一步做的事情是:把Person.class文件加载进内存。在Person.class文件中找到main方法并放到栈。
     *         因为静态是随着类的加载而加载。此时对象this根本就不存在。此时的对象是.class文件(字节码文件)。
     * 
     *         简言之:要想同步,需要先确定同步的对象。
     *                 要在静态同步方法加载之前就得先确定同步的对象,(否则你跟我咋同步)
     *                     谁比静态先存在呢答:只有.class文件(字节码文件)
     *         
     */
    那么,我们到底使用谁?
      如果锁对象是this,就可以考虑使用同步方法。
      否则能使用同步代码块的尽量使用同步代码块。

    示例代码如下:

     1 package cn.itcast_11;
     2 
     3 /*
     4  * 同步可以解决安全问题的根本原因就在那个对象上。
     5  * 
     6  * A:同步代码块的格式及其锁对象是谁呢?
     7  *         格式:
     8  *         synchronized (对象名称) {
     9  *             需要同步的代码;
    10  *         }
    11  * 
    12  *         同步代码块的锁对象是谁呢?
    13  *             任意对象。
    14  * 
    15  * B:同步方法的格式及其锁对象问题?
    16  *         如果一个方法一进去就看到了代码被同步了,那么我就在想能不能把这个同步加在方法上呢? 答:能。
    17  *         把同步关键字加在方法上。
    18  *         格式:
    19  *         synchronized private void sellTicket() {...}
    20  *         private synchronized void sellTicket() {...}    // 习惯上这样写
    21  * 
    22  *         同步方法的锁对象是谁呢?(方法的内部有一个你看不到的对象是this啊,傻瓜哈)
    23  *             this
    24  * 
    25  * C:静态同步方法的格式及其锁对象问题?
    26  *         格式:
    27  *         private static synchronized void sellTicket() {...}
    28  *         
    29  *         静态同步方法的锁对象是谁呢?
    30  *             当前类的字节码文件对象。(反射会讲)
    31  * 
    32  *         类的初始化过程:Person p = new Person(); // 第一步做的事情是:把Person.class文件加载进内存。在Person.class文件中找到main方法并放到栈。
    33  *         因为静态是随着类的加载而加载。此时对象this根本就不存在。此时的对象是.class文件(字节码文件)。
    34  * 
    35  *         简言之:要想同步,需要先确定同步的对象。
    36  *                 要在静态同步方法加载之前就得先确定同步的对象,(否则你跟我咋同步)
    37  *                     谁比静态先存在呢? 答:只有.class文件(字节码文件)
    38  *         
    39  */
    40 public class SellTicketDemo {
    41     public static void main(String[] args) {
    42         // 创建资源对象
    43         SellTicket st = new SellTicket();
    44 
    45         // 创建三个线程对象
    46         Thread t1 = new Thread(st, "窗口1");
    47         Thread t2 = new Thread(st, "窗口2");
    48         Thread t3 = new Thread(st, "窗口3");
    49 
    50         // 启动线程
    51         t1.start();
    52         t2.start();
    53         t3.start();
    54     }
    55 }
    SellTicketDemo.java
      1 package cn.itcast_11;
      2 
      3 public class SellTicket implements Runnable {
      4 
      5     // 定义100张票
      6     private static int tickets = 100;
      7 
      8     // 定义同一把锁为obj对象
      9     private Object obj = new Object();
     10     
     11     // 定义同一把锁为任意对象
     12     private Demo d = new Demo();
     13 
     14     private int x = 0;
     15     
     16     /*
     17     // 同步代码块用obj对象做锁
     18     @Override
     19     public void run() {
     20         while (true) {
     21             synchronized (obj) {
     22                 if (tickets > 0) {
     23                     try {
     24                         Thread.sleep(100);
     25                     } catch (InterruptedException e) {
     26                         e.printStackTrace();
     27                     }
     28                     System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 ");
     29                 }
     30             }
     31         }
     32     }
     33     */
     34     
     35     /*
     36     // 同步代码块用任意对象做锁
     37     @Override
     38     public void run() {
     39         while (true) {
     40             synchronized (d) {
     41                 if (tickets > 0) {
     42                     try {
     43                         Thread.sleep(100);
     44                     } catch (InterruptedException e) {
     45                         e.printStackTrace();
     46                     }
     47                     System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 ");
     48                 }
     49             }
     50         }
     51     }
     52     */
     53     
     54     @Override
     55     public void run() {
     56         while (true) {
     57             if (x % 2 == 0) {
     58                 synchronized (SellTicket.class) {
     59                     if (tickets > 0) {
     60                         try {
     61                             Thread.sleep(100);
     62                         } catch (InterruptedException e) {
     63                             e.printStackTrace();
     64                         }
     65                         System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 ");
     66                     }
     67                 }
     68             } else {
     69                 /*
     70                 synchronized (d) {
     71                     if (tickets > 0) {
     72                         try {
     73                             Thread.sleep(100);
     74                         } catch (InterruptedException e) {
     75                             e.printStackTrace();
     76                         }
     77                         System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 ");
     78                     }
     79                 }
     80                 */
     81                 sellTicket();    
     82             }
     83             x++;
     84         }
     85     }
     86     
     87 
     88     /*
     89     private void sellTicket() {
     90         synchronized (d) {
     91             if (tickets > 0) {
     92                 try {
     93                     Thread.sleep(100);
     94                 } catch (InterruptedException e) {
     95                     e.printStackTrace();
     96                 }
     97                 System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 ");
     98             }
     99         }
    100     }
    101      */
    102     
    103     /*
    104     // 如果一个方法一进去就看到了代码被同步了,那么我就在想能不能把这个同步加在方法上呢? 答:能。
    105     // 同步方法
    106     private synchronized void sellTicket() {
    107         if (tickets > 0) {
    108             try {
    109                 Thread.sleep(100);
    110             } catch (InterruptedException e) {
    111                 e.printStackTrace();
    112             }
    113             System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 ");
    114         }
    115     }
    116      */
    117     
    118     // 静态同步方法
    119     private static synchronized void sellTicket() {
    120         if (tickets > 0) {
    121             try {
    122                 Thread.sleep(100);
    123             } catch (InterruptedException e) {
    124                 e.printStackTrace();
    125             }
    126             System.out.println(Thread.currentThread().getName() + "正在出售第" + (tickets--) + "张票 ");
    127         }
    128     }
    129     
    130 }
    131 
    132 class Demo {
    133 }
    SellTicket.java
  • 相关阅读:
    BNUOJ 12756 Social Holidaying(二分匹配)
    HDU 1114 Piggy-Bank(完全背包)
    HDU 2844 Coins (多重背包)
    HDU 2602 Bone Collector(01背包)
    HDU 1171 Big Event in HDU(01背包)
    HDU 2571 命运 (入门dp)
    HDU 1069 Monkey and Banana(最长递减子序列)
    HDU 1160 FatMouse's Speed (最长上升子序列)
    HDU 2594 KMP
    POJ 3783 Balls --扔鸡蛋问题 经典DP
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/8724716.html
Copyright © 2011-2022 走看看