同步代码块解决线程安全
案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。
代码:
package com.learn;class ThreadDemo01 implements Runnable {// 同时多个窗口共享100private static int count = 100;// 存放方法区中private static Object obj = new Object();public void run() {while (count > 0) {try {Thread.sleep(10);sale();} catch (Exception e) {System.out.println(e.getMessage());}}}public void sale() {synchronized(obj){ if (count > 0) {System.out.println(Thread.currentThread().getName() + ",出售" + (100 - count + 1) + "张票");count--;}}}
}public class Test0001 {public static void main(String[] args) throws InterruptedException {ThreadDemo01 threadDemo01 = new ThreadDemo01();Thread t1 = new Thread(threadDemo01, "窗口1");Thread t2 = new Thread(threadDemo01, "窗口2");t1.start();t2.start();}
}
运行结果:
一号窗口和二号窗口同时出售火车第九九张,部分火车票会重复出售。
结论发现,多个线程共享同一个全局成员变量时,做写的操作可能会发生数据冲突问题。
线程安全解决办法:
问:如何解决多线程之间线程安全问题
答:使用多线程之间同步synchronized或使用锁(lock)。
问:为什么使用线程同步或使用锁能解决线程安全问题呢?
答:将可能会发生数据冲突问题(线程不安全问题),只能让当前一个线程进行执行。代码执行完成后释放锁,让后才能让其他线程进行执行。这样的话就可以解决线程不安全问题。
问:什么是多线程之间同步
答:当多个线程共享同一个资源,不会受到其他线程的干扰。
问:什么是多线程同步
答:当多个线程共享同一个资源,不会受到其他线程的干扰。
内置的锁
Java提供了一种内置的锁机制来支持原子性
每一个Java对象都可以用作一个实现同步的锁,称为内置锁,线程进入同步代码块之前自动获取到锁,代码块执行完成正常退出或代码块中抛出异常退出时会释放掉锁
内置锁为互斥锁,即线程A获取到锁后,线程B阻塞直到线程A释放锁,线程B才能获取到同一个锁
内置锁使用synchronized关键字实现,synchronized关键字有两种用法:
1.修饰需要进行同步的方法(所有访问状态变量的方法都必须进行同步),此时充当锁的对象为调用同步方法的对象
2.同步代码块和直接使用synchronized修饰需要同步的方法是一样的,但是锁的粒度可以更细,并且充当锁的对象不一定是this,也可以是其它对象,所以使用起来更加灵活
同步代码块synchronized
就是将可能会发生线程安全问题的代码,给包括起来。 synchronized(同一个数据){ 可能会发生线程冲突问题 } 就是同步代码块 synchronized(对象)//这个对象可以为任意对象 { 需要被同步的代码 } |
对象如同锁,持有锁的线程可以在同步中执行
没持有锁的线程即使获取CPU的执行权,也进不去
同步的前提:
1,必须要有两个或者两个以上的线程
2,必须是多个线程使用同一个锁
必须保证同步中只能有一个线程在运行
好处:解决了多线程的安全问题
弊端:多个线程需要判断锁,较为消耗资源、抢锁的资源。
思考问题?同步方法使用的是什么锁?
答:同步函数使用this锁。
证明方式: 一个线程使用同步代码块(this明锁),另一个线程使用同步函数。如果两个线程抢票不能实现同步,那么会出现数据错误。
同步代码块解决线程安全相关推荐
- Java20-day11【实现多线程(进程、线程-调度-控制-生命周期)、线程同步(同步代码块、线程安全、Lock)、生产者消费者(模式概述、案例)】
视频+资料[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg 提取码:zjxs] Java基础--学习笔记(零起点打开java世界的大门)--博 ...
- 实现多线程、进程、线程、设置和获取线程名称、线程调度、线程控制、线程生命周期、同步代码块、线程安全的类、Lock锁、生产者消费者模式
实现多线程:
- 黑马毕向东Java课程笔记(day11):多线程(第一部分)——进程与线程+线程创建+线程安全与同步代码块+同步锁/死锁
多线程好文:添加链接描述 锁机制:synchronized.Lock.Condition.volatile(原子性可见性)--参考添加链接描述 1.进程与线程概述 首先,对于CPU执行每一个程序, ...
- Java 编程下的并发线程之间的同步代码块死锁
并发线程之间的死锁通常发生在同步代码块的相互嵌套使用的过程中,下面先来看段代码: package cn.sunzn.synchronize;public class DeadLock {public ...
- java synchronized块_Java多线程同步代码块Synchronized
Java多线程同步代码块Synchronized Java中的每个对象都有一个与之关联的内部锁(Intrinsic lock). 这种锁也称为监视器(Monitor), 这种内部锁是一种排他锁,可以保 ...
- 单例设计模式八种方式——5) 懒汉式(线程安全,同步代码块) 6) 双重检查 7) 静态内部类 8) 枚举
懒汉式(线程安全,同步代码块)应用实例 优缺点说明: 1) 这种方式,本意是想对第四种实现方式的改进,因为前面同步方法效率太低, 改为同步产生实例化的的代码块 2) 但是这种同步并不能起到线程同步的作 ...
- notify()唤醒线程,不会立即释放锁对象,需要等到当前同步代码块都执行完后才能释放锁对象
notify()唤醒线程,不会立即释放锁对象,需要等到当前同步代码块都执行完后才能释放锁对象 public class Test3 {public static void main(String[] ...
- 基本线程同步(五)使用Lock同步代码块
声明:本文是< Java 7 Concurrency Cookbook >的第二章,作者: Javier Fernández González 译者:许巧辉 校对:方腾飞 使用Lo ...
- java 线程 wait 一定要同步_java中使用wait就得使用同步锁,而且2个线程必须都使用同步代码块,否则就会异常...
标签: 标题已经说明,子线程wai()时候默认的锁不是同步代码块的锁,因此wai时候显示的指明锁,现在解释看code: public class Test { //staticboolean flag ...
最新文章
- 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能...
- php mysql try catch_PHP的try catch有多大意义?
- Spring集成MyBatis框架
- PC上虚拟机中安装NW 7.02 ABAP试用版
- [源码和文档分享]基于C++实现的运动会统分系统
- 多线程并发如何高效实现生产者/消费者?
- DCT原型 ——傅里叶级数
- 用户级别线程的切换切换到内核线程_【修炼内功】[JVM] 细说线程
- 关于领域驱动设计与面向数据库设计
- 科来无线抓包基础知识扫盲
- Survivor空间溢出实例
- nginx源码编译安装和配置
- NLPIR-JAVA版本-MAC-LINUX-WINDOWS操作系统均适用
- 从0开始的技术美术之路(十)伽马校正
- 会议室选多大尺寸的会议平板才合适?
- kali2021.1安装pdtools挤牙膏式爬坑日记
- 罗丹明 PEG 巯基,Rhodamine PEG Thiol,荧光染料标记巯基/硫醇
- iOS微信小程序网页请求走error问题
- SCRCPY与Android操作流程(华为手机) 原创超详细
- mc服务器称号显示插件,[聊天]UDtitle ——称号管理(仓库) 1.1.6 [全版本]