java多线程---4 线程同步介绍及不安全案例说明
java多线程---4 线程同步介绍及不安全案例说明
线程同步
并发: 同一个对象被多个线程同时操作。
- 处理多线程问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象,这时候我们就需要线程同步。
- 线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等待前面线程使用完毕,下一个线程再使用。
- 形成条件:队列+锁
锁:
- 由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制synchronized, 当一个线程获得对象的排它锁,独占资源,其他线程必须等待!
- 由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制同步,当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可。
- 存在以下问题:使用后释放锁即可.存在以下问题:
- 一个线程持有锁会导致其他所有需要此锁的线程挂起。
- 在多线程竞争下,加锁,释放锁会导致比较多的上下文切换 和 调度延迟,引起性能问题。
- 如果一个优先级高的线程等待一个优先级低的线程释放锁,会导致优先级倒置,引起性能问题。
不安全的线程操作案例
- 不安全的买票
package com.ssl.demo04;
//不安全的买票
//线程不安全,会出负数
public class UnsafeBuyTicket {
public static void main(String[] args) {
BuyTicket buyTicket = new BuyTicket();
new Thread(buyTicket,"小明").start();
new Thread(buyTicket,"黄牛").start();
new Thread(buyTicket,"小红").start();
}
}
class BuyTicket implements Runnable{
private int ticketNums = 10;
boolean flag = true; //外部停止方式
@Override
public void run() {
//买票
while(flag){
buy();
}
}
private void buy(){
//判断是否有票
if (ticketNums <= 0){
flag = false;
return;
}
//模拟延时
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//买票
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
}
- 不安全的银行
package com.ssl.demo04;
//不安全的取钱
//两个人去银行取钱,账户
public class UnsafeBank {
public static void main(String[] args) {
//账户
Account account = new Account(100,"结婚基金");
//取钱过程
Drawing you = new Drawing(account,80,"你");
Drawing girlFriend = new Drawing(account,100,"女友");
you.start();
girlFriend.start();
}
}
//账户
class Account{
int money; //余额
String name; //卡名
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
//银行:模拟取款
class Drawing extends Thread{
Account account; //账户
//取了多少钱
int drawingMoney;
//现在手里有多少钱
int nowMoney;
public Drawing(Account account,int drawingMoney, String name){
super(name);
this.account = account;
this.drawingMoney = drawingMoney;
}
@Override
public void run() {
//判断有没有钱
if(account.money-drawingMoney < 0){
System.out.println(Thread.currentThread().getName()+"钱不够,取钱失败");
return;
}
//sleep 放大问题的发生性
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//卡内余额 = 余额 - 你取的钱
account.money = account.money - drawingMoney;
//手里的钱
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name + " 余额为:"+account.money);
//this.getName() 等价于 Thread.currentThread().getName()
System.out.println(this.getName()+"手里的钱"+nowMoney);
}
}
- 不安全的线程集合
package com.ssl.demo04;
import java.util.ArrayList;
import java.util.List;
//线程不安全的集合
public class UnsafeList {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
list.add(Thread.currentThread().getName());
}).start();
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//存在数据覆盖的情况 总数不到10000
System.out.println(list.size());
}
}
java多线程---4 线程同步介绍及不安全案例说明的更多相关文章
- 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)
Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...
- java多线程:线程同步synchronized(不同步的问题、队列与锁),死锁的产生和解决
0.不同步的问题 并发的线程不安全问题: 多个线程同时操作同一个对象,如果控制不好,就会产生问题,叫做线程不安全. 我们来看三个比较经典的案例来说明线程不安全的问题. 0.1 订票问题 例如前面说过的 ...
- Java多线程 3 线程同步
在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的 ...
- Java多线程与线程同步
六.多线程,线程,同步 ①概念: 并行:指两个或多个在时间同一时刻发生(同时发生) 并发:指两个或多个事件在同一时间段内发生 具体概念: 在操作系统中,安装了多个程序,并发指的是在一段时间内宏观上有多 ...
- Java多线程 | 02 | 线程同步机制
同步机制简介 线程同步机制是一套用于协调线程之间的数据访问的机制.该机制可以保障线程安全.Java平台提供的线程同步机制包括: 锁,volatile关键字,final关键字,static关键字,以 ...
- Java多线程之线程同步【synchronized、Lock、volatitle】
线程同步 线程同步:当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作, 其他线程才能对该内存地址进行操作,而其他线程又处于等待状态,实现线程同步的方法有很多. ...
- java ->多线程_线程同步、死锁、等待唤醒机制
线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的. l 我们通过一个案例,演示线 ...
- java 多线程 day03 线程同步
package com.czbk.thread; /** * Created by chengtao on 17/12/3. 线程安全问题: 线程安全出现 的根本原因: 1. 存在两个或者两个以上 的 ...
- Java多线程之线程的同步
Java多线程之线程的同步 实际开发中我们也经常提到说线程安全问题,那么什么是线程安全问题呢? 线程不安全就是说在多线程编程中出现了错误情况,由于系统的线程调度具有一定的随机性,当使用多个线程来访问同 ...
- Java多线程02(线程安全、线程同步、等待唤醒机制)
Java多线程2(线程安全.线程同步.等待唤醒机制.单例设计模式) 1.线程安全 如果有多个线程在同时运行,而这些线程可能会同时运行这段代码.程序每次运行结果和单线程运行的结果是一样的,而且其他的变量 ...
随机推荐
- Django基础篇 04-模型类注册到后台Django Admin中
一.django自带的admin的url地址 urls.py文件中 from django.contrib import admin from django.urls import path from ...
- vue 项目打包 遇到问题 npm run build 无法打包
npm run build 打包 直接报错!!! 发现package.json中build的打包后边多了一个:prod 因此打包直接使用 npm run build:prod
- Calendar设定月份时要注意日期
先看下代码 public static void main(String[] args) { int dataMonth = 4; DateFormat dateFormat = new Simple ...
- [杂谈吐槽]UE国内社区环境
此篇博客是我个人想法,当然也是不争的事实,如果您有意见,那您也是我说那些人其中的一员. --此部分为社区环境差最恶劣的原因-- 国内的虚幻社区环境可以说不能再烂了,虚幻商城和虚幻引擎的蓝图是非常强大的 ...
- 在vscode中用tsc编译ts文件的时候报错,tsc : 无法加载文件,因为在此系统上禁止运行脚本;SecurityError
1. TypeScript安装成功,在C盘的Administrator目录下,运行 tsc -v 也可看到TypeScript的版本. 2. 但在vscode中的时候运行tsc 编译ts文件的时候报 ...
- Resnet网络--BasicBlock与BottleNeck
ResNetV2的网络深度有18,34,50,101,152.50层以下的网络基础块是BasicBlock,50层及以上的网络基础块是BottleNeck. BasicBlock 图示如下 代码实现 ...
- C++语法难点
virtual 实现类的多态性:基类定义虚函数,子类可以重写该函数:如果使用了virtual关键字,程序将根据引用或指针指向的 对象类型 来选择方法,否则使用引用类型或指针类型来选择方法 实现虚继承, ...
- IT工具知识-10:Markdown小技巧(不断更新)
Markdown小技巧 1. 如何实现在文内不同关键字间跳转 该技巧是基于typora软件下使用的,参考的这个教程:视频链接 该教程有两种跳转方式:一.使用Markdown语法,二.使用HTML的锚点 ...
- linux查看IP地址
方法一:ifconfig -a 方法二:ip addr
- Unity UI布局与适配
目录 Canvas(画布) Basic Layout(基础布局) 实例 1.画布(Canvas) 画布是所有UI元素的父物体,任何UI元素都存在于画布之上.画布上所有UI元素的绘制顺序是根据其在场景中 ...