• java 多线程安全--- synchronized 关键字


    1.什么线程安全问题?

    1.1 就是当多个线程共享同一个全局变量,同时对这个变量做写的时间,可能会受到其他线程的干扰,导致数据有误。


    class ThreadDemos implements Runnable {
    private int movie = 8;

    @Override
    public void run() {
    while (movie > 0) {
    try {
    Thread.sleep(10);
    } catch (Exception e) {
    // TODO: handle exception
    }
    sell();
    }
    }

    public void sell() {
    if (movie > 0) {
    System.out.println(Thread.currentThread().getName() + ",出售第" + (8 - movie + 1) + "票");
    movie--;

    }


    }
    }

    public class ThreadDemo {

    public static void main(String[] args) {
    ThreadDemos threadDemos = new ThreadDemos();
    Thread t1 = new Thread(threadDemos, "美团买票");
    Thread t2 = new Thread(threadDemos, "门店买票");
    t1.start();
    t2.start();
    }

    }

    运行结果:

     由此我们可以发现2个窗口会出现同一张票,就出现了线程安全问题,如果2个不同的人买了同一张票,这个时间检票员是该让哪个人进去看电影那?

    2.怎么样解决线程安全问题?

    2.1 使用synchronized 同步代码块  代码如下:


    class ThreadDemos implements Runnable {
    private int movie = 8;
    private Object object = new Object();

    @Override
    public void run() {
    while (movie > 0) {
    try {
    Thread.sleep(10);
    } catch (Exception e) {
    // TODO: handle exception
    }
    sell();
    }
    }

    public void sell() {
    synchronized (object) {
    if (movie > 0) {
    System.out.println(Thread.currentThread().getName() + ",出售第" + (8 - movie + 1) + "票");
    movie--;

    }
    }


    }
    }

    public class ThreadDemo {

    public static void main(String[] args) {
    ThreadDemos threadDemos = new ThreadDemos();
    Thread t1 = new Thread(threadDemos, "美团买票");
    Thread t2 = new Thread(threadDemos, "门店买票");
    t1.start();
    t2.start();
    }

    }
    代码运行结果:

    使用 synchronized 同步代码块 就不会出现2个窗口会出现同一张票的安全性问题

    使用synchronized 的  条件:1.必须要有2个线程以上的,需要同步  2.多个线程想要同步,必须要使用同一把锁 3.保证只有一个线程运行执行

    使用synchronized 同步代码块 的原理:有一个线程已经拿到锁了,其他线程已经有cpu执行的,那么这个线程会等待拿到锁的那个线程执行完毕释放锁

    使用synchronized 的缺点:效率低,因为线程会抢锁

    2.2使用 同步函数解决线程安全:


    class ThreadDemos implements Runnable {
    private int movie = 8;

    @Override
    public void run() {
    while (movie > 0) {
    try {
    Thread.sleep(10);
    } catch (Exception e) {
    // TODO: handle exception
    }
    sell();
    }
    }

    public synchronized void sell() {
    if (movie > 0) {
    System.out.println(Thread.currentThread().getName() + ",出售第" + (8 - movie + 1) + "票");
    movie--;

    }


    }
    }

    public class ThreadDemo05 {

    public static void main(String[] args) {
    ThreadDemos threadDemos = new ThreadDemos();
    Thread t1 = new Thread(threadDemos, "美团买票");
    Thread t2 = new Thread(threadDemos, "门店买票");
    t1.start();
    t2.start();
    }

    }
    代码运行结果:

     使用同步函数 在需要同步的方法上面加上  synchronized 关键字,同步函数使用的是 this 锁

    2.3使用静态同步函数

    class ThreadDemos implements Runnable {
    private static int movie = 8;

    @Override
    public void run() {
    while (movie > 0) {
    try {
    Thread.sleep(10);
    } catch (Exception e) {
    // TODO: handle exception
    }
    sell();
    }
    }

    public static synchronized void sell() {

    if (movie > 0) {
    System.out.println(Thread.currentThread().getName() + ",出售第" + (8 - movie + 1) + "票");
    movie--;

    }


    }
    }

    public class ThreadDemo05 {

    public static void main(String[] args) {
    ThreadDemos threadDemos = new ThreadDemos();
    Thread t1 = new Thread(threadDemos, "美团买票");
    Thread t2 = new Thread(threadDemos, "门店买票");
    t1.start();
    t2.start();
    }

    }
    运行结果:

    静态同步函数使用的是 当前字节码文件

  • 相关阅读:
    1.27
    1.25
    Representation Learning with Contrastive Predictive Coding
    Learning a Similarity Metric Discriminatively, with Application to Face Verification
    噪声对比估计(负样本采样)
    Certified Adversarial Robustness via Randomized Smoothing
    Certified Robustness to Adversarial Examples with Differential Privacy
    Dynamic Routing Between Capsules
    Defending Adversarial Attacks by Correcting logits
    Visualizing Data using t-SNE
  • 原文地址:https://www.cnblogs.com/cwj1102/p/13354381.html
Copyright © 2020-2023  润新知