java 阻塞锁_Java并发,synchronized锁住的内容

synchronized用在方法上锁住的是什么?

锁住的是当前对象的当前方法,会使得其他线程访问该对象的synchronized方法或者代码块阻塞,但并不会阻塞非synchronized方法。

脏读

一个常见的概念。在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数据其实是被更改过的。注意这里 局部变量是不存在脏读的情况

public classThreadDomain13

{private int num = 0;public voidaddNum(String userName)

{try{if ("a".equals(userName))

{

num= 100;

System.out.println("a set over!");

Thread.sleep(2000);

}else{

num= 200;

System.out.println("b set over!");

}

System.out.println(userName+ " num = " +num);

}catch(InterruptedException e)

{

e.printStackTrace();

}

}

}

写两个线程分别去add字符串"a"和字符串"b":

public class MyThread13_0 extendsThread

{privateThreadDomain13 td;publicMyThread13_0(ThreadDomain13 td)

{this.td =td;

}public voidrun()

{

td.addNum("a");

}

}public class MyThread13_1 extendsThread

{privateThreadDomain13 td;publicMyThread13_1(ThreadDomain13 td)

{this.td =td;

}public voidrun()

{

td.addNum("b");

}

}

写一个主函数分别运行这两个线程:

public static voidmain(String[] args)

{

ThreadDomain13 td= newThreadDomain13();

MyThread13_0 mt0= newMyThread13_0(td);

MyThread13_1 mt1= newMyThread13_1(td);

mt0.start();

mt1.start();

}//看一下运行结果

a set over!b set over!b num= 200a num= 200

按照正常来看应该打印"a num = 100"和"b num = 200"才对,现在却打印了"b num = 200"和"a num = 200",这就是线程安全问题。我们可以想一下是怎么会有线程安全的问题的:

1、mt0先运行,给num赋值100,然后打印出"a set over!",开始睡觉

2、mt0在睡觉的时候,mt1运行了,给num赋值200,然后打印出"b set over!",然后打印"b num = 200"

3、mt1睡完觉了,由于mt0的num和mt1的num是同一个num,所以mt1把num改为了200了,mt0也没办法,对于它来说,num只能是100,mt0继续运行代码,打印出"a num = 200"

分析了产生问题的原因,解决就很简单了,给addNum(String userName)方法加同步即可:

多线程线synchronized关键字加到方法上

public classThreadDomain13

{private int num = 0;public synchronized voidaddNum(String userName)

{try{if ("a".equals(userName))

{

num= 100;

System.out.println("a set over!");

Thread.sleep(2000);

}else{

num= 200;

System.out.println("b set over!");

}

System.out.println(userName+ " num = " +num);

}catch(InterruptedException e)

{

e.printStackTrace();

}

}

}

复制代码

看一下运行结果:

a set over!a num= 100b set over!b num= 200

多个对象多个锁

在同步的情况下,把main函数内的代码改一下:

public static voidmain(String[] args)

{

ThreadDomain13 td0= newThreadDomain13();

ThreadDomain13 td1= newThreadDomain13();

MyThread13_0 mt0= newMyThread13_0(td0);

MyThread13_1 mt1= newMyThread13_1(td1);

mt0.start();

mt1.start();

}

看一下运行结果:

a set over!b set over!b num= 200a num= 100

这里有一个重要的概念。关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当作锁,这里如果是把一段代码或方法(函数)当作锁,其实获取的也是对象锁,只是监视器(对象)不同而已,哪个线程先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁,其他线程都只能呈等待状态。但是这有个前提:既然锁叫做对象锁,那么势必和对象相关,所以多个线程访问的必须是同一个对象。

如果多个线程访问的是多个对象,那么Java虚拟机就会创建多个锁,就像上面的例子一样,创建了两个ThreadDomain13对象,就产生了2个锁。既然两个线程持有的是不同的锁,自然不会受到"等待释放锁"这一行为的制约,可以分别运行addNum(String userName)中的代码。

synchronized(this)锁住的是什么?

锁住的是当前的对象。当synchronized块里的内容执行完之后,释放当前对象的锁。同一时刻若有多个线程访问这个对象,则会被阻塞。

synchronized(object)锁住的什么?

锁住的是object对象。当synchronized块里的内容执行完之后,释放object对象的锁。同一时刻若有多个线程访问这个对象,则会被阻塞。

这里需要注意的是如果object为Integer、String等等包装类时(new出的对象除外),并不会锁住当前对象,也不会阻塞线程。因为包装类是final的,不可修改的,如果修改则会生成一个新的对象。所以,在一个线程对其进行修改后,其他线程在获取该对象的锁时,该对象已经不是原来的那个对象,所以获取到的是另一个对象的锁,所以不会产生阻塞。

Java中Synchronized的用法:https://blog.csdn.net/luoweifu/article/details/46613015

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值