• (对于继承Thread类)线程安全问题解决方式一:同步代码块


     1 package day2_4;
     2 
     3 /**
     4  *例子:创建三个窗口卖票,总票数为100张,使用实现Runnable接口
     5  * 1.问题:卖票过程中,出现了重票、错票的情况 --->出现了线程安全问题
     6  * 2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票
     7  * 3.如何解决:当一个线程A在操作ticket时,其他线程不能参与进来,直到线程A操作完(即使A出现阻塞),其他线程才可以开始
     8  *          才做操作ticket
     9  * 4.在Java中我们通过同步机制,来解决线程的安全问题
    10  *
    11  * 方式一:同步代码块
    12  *
    13  *  synchronized(同步监视器){
    14  *      //需要被同步的代码
    15  *  }
    16  *
    17  *  说明:1.操作共享数据的代码,就是需要被同步的代码  -->不能包含代码少了,也不能包含代码多了(1.可以会改变逻辑 2.效率变低)
    18  *       2.共享数据:多个线程共同操作的变量,比如ticket就是共享数据
    19  *       3.同步监视器:俗称锁。任何一个类的对象都可以充当锁
    20  *          要求:多个线程必须共用同一把锁(也就是多个线程共享的一个对象)
    21  *
    22  *          补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this来充当同步监视器
    23  *          说明:但是在继承Thread类创建多线程的方式中,慎用this充当同步监视器,可以考虑使用
    24  *               线程类的类对象充当同步监视器
    25  * 
    26  * @Author Tianhao
    27  * @create 2021-02-04-21:31
    28  */
    29 
    30 class Window4 extends Thread {
    31     //加上static保证多个线程共享
    32     private static int ticket = 100;
    33     //加上static保证多个线程共享
    34     private static Object obj = new Object();
    35 
    36     @Override
    37     public void run() {
    38         while (true) {
    39             //错误的
    40             //synchronized(this){  //this 表示w1,w2,w3,不是这三个线程共享的对象,所以不能充当同步监视器
    41             //正确的
    42             //synchronized (obj) {
    43             synchronized(Window4.class){  // Class clazz = Window4.class 每个类的类对象是唯一的
    44                 if (ticket > 0) {
    45                     try {
    46                         sleep(100);
    47                     } catch (InterruptedException e) {
    48                         e.printStackTrace();
    49                     }
    50                     System.out.println(getName() + "卖票,票号:" + ticket);
    51                     ticket--;
    52                 } else {
    53                     break;
    54                 }
    55             }
    56         }
    57     }
    58 }
    59 
    60 public class WindowTest4 {
    61     public static void main(String[] args) {
    62         Window4 w1 = new Window4();
    63         Window4 w2 = new Window4();
    64         Window4 w3 = new Window4();
    65         w1.setName("窗口1");
    66         w2.setName("窗口2");
    67         w3.setName("窗口3");
    68         w1.start();
    69         w2.start();
    70         w3.start();
    71     }
    72 }
  • 相关阅读:
    POJ 3356 水LCS
    POJ 2250 (LCS,经典输出LCS序列 dfs)
    POJ 1080( LCS变形)
    整数划分问题之最大乘积
    进程调度之FCFS算法(先来先运行算法)
    c模拟银行家资源分配算法
    c模拟内存分配算法(首次适应算法,最佳适应算法,最坏适应算法)
    HDU 2602 Bone Collector(经典01背包问题)
    NYOJ 44 字串和 (最大字串和 线性dp)
    匈牙利游戏(codevs 1269)
  • 原文地址:https://www.cnblogs.com/zui-ai-java/p/14377481.html
Copyright © 2020-2023  润新知