zoukankan      html  css  js  c++  java
  • 线程安全的3种方式

    1 多线程容易出现问题

    举个例子,电影院卖票,一共卖100张票,分3个窗口,用多线程来模拟,看会发生什么?

    1-1 创建一个卖票任务,实现Runnable接口

    public class Ticket implements Runnable{
    
    //    总共100
        private int ticket = 100;
    
        @Override
        public void run() {
            while (true){
                if (ticket>0){
                    try {
    //                    处理卖票耗时
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    String name = Thread.currentThread().getName();
                    System.out.println(name+"正在卖票"+ticket--);
                }
            }
    
        }
    }
    
    

    1-2 创建3个线程,来卖票

    public class Test {
        public static void main(String[] args) {
            Ticket ticket = new Ticket();
            Thread t1 = new Thread(ticket, "线程1");
            Thread t2 = new Thread(ticket, "线程2");
            Thread t3 = new Thread(ticket, "线程3");
    
            t1.start();
            t2.start();
            t3.start();
        }
    }
    
    

    1-3 出现的问题

    • 相同的票被卖了2次,如下图
      屏幕快照 2020-03-12 下午10.08.33.png
    • 不存在的票,如0或者1
      屏幕快照 2020-03-12 下午10.09.42.png
      若有多个线程同时执行写的操作,那么需要考虑线程同步,否则的话,可能影响线程安全。

    2 同步代码块 synchronized

    synachronized(同步锁){
              需要同步操作的代码
    }
    

    2-1 使用同步锁的方式来创建Runnable的实现类

    public class Ticket implements Runnable{
    
    //    总共100
        private int ticket = 100;
    
        Object obj = new Object();
    
        @Override
        public void run() {
            while (true){
                synchronized (obj){
                    if (ticket>0){
                        try {
    //                    处理卖票耗时
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        String name = Thread.currentThread().getName();
                        System.out.println(name+"正在卖票"+ticket--);
                    }
                }
            }
    
        }
    }
    
    

    3 使用同步方法来解决线程安全

    使用synchronized修饰的方法,就是同步方法,可以保证一个线程执行该方法的同时,其它的线程只能在方法的外边等候

    public class Ticket implements Runnable{
    
    //    总共100
        private int ticket = 100;
    
    
        @Override
        public void run() {
            while (true){
                sellTicket();
            }
    
        }
    
        public synchronized void sellTicket(){
            if (ticket>0){
                try {
    //                    处理卖票耗时
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String name = Thread.currentThread().getName();
                System.out.println(name+"正在卖票"+ticket--);
            }
        }
    }
    
    

    4 使用lock锁

    synachronized(同步锁){
              需要同步操作的代码
    }
    

    2-1 使用同步锁的方式来创建Runnable的实现类

    public class Ticket implements Runnable{
    
    //    总共100
        private int ticket = 100;
    
    Lock lock = new ReentrantLock();    
    
        @Override
        public void run() {
            while (true){
                lock.lock();
                 if (ticket>0){
                        try {
    //                    处理卖票耗时
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        String name = Thread.currentThread().getName();
                        System.out.println(name+"正在卖票"+ticket--);
                    }
                  lock.unlock();
           }
    
        }
    }
    
    
  • 相关阅读:
    《大话数据结构》第1章 数据结构绪论 1.2 你数据结构怎么学的?
    伍迷七八月新浪微博集锦
    《大话数据结构》第9章 排序 9.7 堆排序(下)
    《大话数据结构》第3章 线性表 3.8.2 单链表的删除
    《大话数据结构》第9章 排序 9.5 直接插入排序
    《大话数据结构》第9章 排序 9.8 归并排序(上)
    《大话数据结构》第2章 算法基础 2.9 算法的时间复杂度
    《大话数据结构》第1章 数据结构绪论 1.1 开场白
    《大话数据结构》第9章 排序 9.1 开场白
    [AWS] Assign a public IP address to an EC2 instance after launched
  • 原文地址:https://www.cnblogs.com/hellosiyu/p/12483304.html
Copyright © 2011-2022 走看看