zoukankan      html  css  js  c++  java
  • java线程安全

    什么是线程安全问题?

    当多个线程共享同一个全局变量,修改的时候,可能会受到其他线程干扰,导致数据有问题,这就现象叫做线程安全问题。读的时候,不会产生线程安全问题

    多个线程共享一个局部变量,对变量修改时不会对发生线程安全问题

    示例:车站卖票经典案例

    public class ThreadDemo implements Runnable {
        //一共有一百张票
        private int count = 100;
    
        @Override
        public void run() {
            while (count > 0) {
                try {
                    Thread.sleep(100);
                    sale();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        private void sale() {
            if (count > 0) {
                System.out.println(Thread.currentThread().getName() + "出售第" + (100 - count + 1) + "张票");
                count--;
            }
        }
    
        public static void main(String[] args) {
            ThreadDemo threadDemo = new ThreadDemo();
            Thread t1 = new Thread(threadDemo, "窗口1");
            Thread t2 = new Thread(threadDemo, "窗口2");
            t1.start();
            t2.start();
        }
    }

    观察输出发现很多重复票出售。

    如何解决线程安全问题?

    synchroizcd    --手动锁

    lock  --jdk1.5并发包 --手动

    使用synchroizcd解决线程安全问题

    private synchronized void sale() {
            if (count > 0) {
                System.out.println(Thread.currentThread().getName() + "出售第" + (100 - count + 1) + "张票");
                count--;
            }
        }

    原理:
    1、对一段代码块加锁了之后,当第一个线程执行到这段加锁的代码块后就会先拿到一个锁,这时其他线程就不能执行这段加锁的代码块了,会在外面等待。因为锁已经被另一个线程拿到了,只有拿到锁的线程才能执行这段加锁的代码块,当第一个拿到锁的线程把锁释放后,这时其他线程就可以去抢这把锁了,当有一个线程抢到锁后,其他线程就只能继续等待锁释放。

    2、锁是什么时候释放?代码执行完毕或者是程序抛出异常锁都会被释放

    3、锁已经被释放的话,其他线程开始抢这把锁,执行同步代码块

    什么地方需要考虑加锁?

    1.有两个线程以上,需要发生同步

    2.多个线程想同步,必须要用同意把锁。

    3.保证同一时刻只有一个线程进行执行。

    好处:解决了多线程的安全问题 

    弊端:多个线程需要判断锁,较为消耗资源、抢锁的资源。

    什么是同步代码块?

    就是将可能会发生线程安全问题的代码,给包括起来

    synchronized(同一个对象){
        //可能会发生线程冲突问题
    }

    对象如同锁,持有锁的线程可以在同步中执行 

    同步函数:就是在方法上加上 synchronized

    同步函数 使用什么锁?  this锁。

    一个线程使用同步代码块(this明锁),另一个线程使用同步函数。如果两个线程抢票不能实现同步,那么会出现数据错误。

    静态同步函数

    方法上加上static关键字,使用synchronized 关键字修饰 或者使用类.class文件。

    静态的同步函数使用的锁是  该函数所属字节码文件对象

    可以用 getClass方法获取,也可以用当前  类名.class 表示。

    多线程死锁问题:

    产生场景:初学者喜欢每个地方都加入synchronized,于是synchronized中嵌套synchronized,容易产生死锁

    产生原因:A线程拿到了锁2,现在需要拿锁1;B线程拿了锁1,现在需要拿锁2;A线程拿不到锁1就不会释放锁2;B线程拿不到锁2就不会释放锁1

    Java内存模型

    多线程有三大特性

    原子性、可见性、有序性

    什么是原子性

    即一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断。要么就都不执行。

    有序性

    程序执行的顺序按照代码的先后顺序执行

  • 相关阅读:
    跟踪spring MVC的请求
    spring的Java注解方式
    spring IOC理解
    spring aop
    spring mvc开发过程中的乱码问题
    springmvc的Controller里实现转发的同时弹出提示对话框
    C++程序加速的12个方法
    VSCode官方配置C/C++
    VSCode配置C/C++环境
    Numba 0.44 中文文档
  • 原文地址:https://www.cnblogs.com/DepthCh/p/12177233.html
Copyright © 2011-2022 走看看