首页 > 其他分享 >synchronized一个有趣现象

synchronized一个有趣现象

时间:2023-05-28 18:11:58浏览次数:45  
标签:Thread synchronized -- number myThread 现象 number1 new 有趣

在学习synchronized时发现了一个有趣的现象:

public class MyThread implements  Runnable {
    private int number=10;
    private  boolean flag = true;
    @Override
    public  void run() {
        while (flag) {
            //同步块,()填变化的量必须是引用类型,锁定的就是传入参数
            synchronized (Integer.valueOf(number)){
                number--;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (number < 1) {
                    flag=false;
                }
                else {
                    System.out.println(Thread.currentThread().getName() + "--" + number);
                }
            }
            }
        }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        new Thread(myThread,"李").start();
        new Thread(myThread,"马").start();
        new Thread(myThread,"王").start();
    }
}

/*
李--7
马--7
王--7
王--4
李--4
马--4
李--1
马--1
王--1

我以为只有在一个线程执行完同步块后另外一个线程才有机会进入,但上述情况却像是一旦对同步监视器的相关操作(加减乘除)结束后其他线程就已经可以进入同步块了,以至于造成上述情况:李在进入后执行减操作,之后休眠,同时马进入同样执行减操作后休眠,王重复上述操作,在三者都先后执行完休眠操作,但是此时的number却已经被减了三次了使用呈现上述的删除结果

再做一次实验:

public class MyThread implements  Runnable {
    private static Integer number=10;
    private static Integer number1=10;
    private  boolean flag = true;
    @Override
    public  void run() {
        while (flag) {
            synchronized (number){
                if (number < 1) {
                    flag=false;
                }
                else {
                    System.out.println(Thread.currentThread().getName() + "--number--" +number);
                    number--;
                    System.out.println(Thread.currentThread().getName() + "--number1--" +number1--);
                }
            }
            }
        }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        new Thread(myThread,"李").start();
        new Thread(myThread,"马").start();
        new Thread(myThread,"王").start();
    }
}

/*
李--number--10
李--number1--10
李--number--9
李--number1--9
王--number--9
李--number--8
王--number1--8
李--number1--7
马--number--6
王--number--6
马--number1--6
王--number1--5
马--number--4
李--number--4
马--number1--4
李--number1--3
马--number--2
王--number--2
马--number1--2
王--number1--1

可以看到number出现了多次重复,number1却完全没有。可以看出好像只会在操作同步监视器的那一行上锁一样。我以为只有在一个线程执行完同步块后另外一个线程才有机会进入。这是我的一个误区。同步块中最好还是就写相关的操作吧

标签:Thread,synchronized,--,number,myThread,现象,number1,new,有趣
From: https://www.cnblogs.com/rainaftersummert/p/17438604.html

相关文章

  • 算法学习 | 从几个有趣的故事说起,聊聊里面的算法
    前言提到故事我就来劲头了。一方面,我喜欢读故事、讲故事、搜集故事,另一方面,用讲故事的方式会为学习增加一些趣味性,有兴趣可以帮助坚持下去。下面要介绍的故事,有些大家应该不陌生。我之前有读到过,但是没有认真的研究过,有种熟悉的陌生感。今天分享读了的故事、研究了的解题过程、顺便......
  • java 多线程:synchronized 详解
    总结一个锁对象只能同时被一个线程持有,分为对象锁和类锁对象锁:每个对象都可以作为锁(几个不同的对象就是几个锁)类锁:字节码对象也能作为锁(全局唯一)同步方法不能自定义锁,只能是默认的锁(非静态:this,静态:class);同步代码块默认的锁和方法一样(非静态:this,静态:class,普通方法里面可以......
  • 算法学习 | 从几个有趣的故事说起,聊聊里面的算法
    前言提到故事我就来劲头了。一方面,我喜欢读故事、讲故事、搜集故事,另一方面,用讲故事的方式会为学习增加一些趣味性,有兴趣可以帮助坚持下去。下面要介绍的故事,有些大家应该不陌生。我之前有读到过,但是没有认真的研究过,有种熟悉的陌生感。今天分享读了的故事、研究了的解题过程、顺便......
  • Java-Day-23( 线程二:线程终止 + 常用方法 + 用户线程 + 守护线程 + 线程生命周期 + Syn
    Java-Day-23线程终止setLoop()基本说明当线程完成任务后,会自动退出还可以通过使用变量来控制run方法退出的方式停止线程,即通知方式练习使用publicclasstest1{publicstaticvoidmain(String[]args)throwsInterruptedException{Tt1=newT();......
  • synchronized原理
    `synchronized`是Java中用来实现线程同步的关键字,它的主要作用是对代码块或方法进行加锁,保证在同一时刻只有一个线程能够执行被加锁的代码块或方法,从而避免多个线程同时访问共享资源导致的数据不一致问题。`synchronized`的实现原理是基于Java对象头中的monitor(监视器)实......
  • 彻底理解synchronized(转载)
    synchronized简介在学习知识前,我们先来看一个现象:publicclassSynchronizedDemoimplementsRunnable{privatestaticintcount=0;publicstaticvoidmain(String[]args){for(inti=0;i<10;i++){Threadthread=newThread(n......
  • synchronized、Lock 为什么要设计成可重入
    为什么监视器锁(ObjectMonitor)、Lock要设计成可重入的目的主要有两个1、防止死锁2、面向对象更好的封装代码先看一段代码@Slf4jpublicclassSynchronizedDemo{privatestaticfinalObjectlock=newObject();publicstaticvoidmain(String[]args){......
  • 有趣的前端小游戏
    今天搬了一天的家,状态不是很好,分享一个小游戏给大家吧~先介绍一下游戏规则:1、点击play后,游戏会提供4中不同的昆虫供玩家进行选择,这四种昆虫分别为:蟑螂、蛛蛛、蚊子和苍蝇。2、当玩家选择完昆虫后,游戏开始3、游戏会随机的生成玩家选择的昆虫到电脑屏幕,玩家利用鼠标点击到则得一分......
  • Salesforce LWC学习(四十四) Datatable 显示日期类型的有趣点思考
    本篇参考:https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.reference_salesforce_modules背景:项目中经常用到datatable显示日期类型字段,并要求日期类型字段基于指定格式显示。这种是一个很常见的需求,而且demo很容易找到,无论是官方文档中还是......
  • 粘包现象structmok
     ......