java 22 - 12 多线程之解决线程安全问题的实现方式1
从上一章知道了多线程存在着线程安全问题,那么,如何解决线程安全问题呢?
导致出现问题的原因:
A:是否是多线程环境
B:是否有共享数据
C:是否有多条语句操作共享数据
上一章的程序,上面那3条都具备,所以肯定出问题。
如何解决问题:
原因A、B肯定不能改变,所以只能改变原因C
解决问题思路:
如果把多条语句操作共享数据的代码给包成一个整体,让某个线程在执行这个整体的时候,别的线程不能执行。
这时候就用到了java提供的:同步机制
同步代码块:
synchronized(对象){
需要同步的代码;
}
问题:
A:这里的对象是什么?
可以随便创建一个对象,例如:Object
B:需要同步的代码块有哪些?
多条语句操作共享数据的代码块
注意:
同步机制可以解决安全的根本原因就在于同步代码块中的对象上,
这个对象就相当于锁的功能,而多个线程必须是同一把锁。
同步的总结:
同步的特点:
前提:多线程
注意:多个线程使用的是同一个锁对象
同步的好处:
解决了多线程的安全问题
同步的弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。
代码例子:
自定义多线程类
public class SellTicket implements Runnable {
// 定义100张票
private int tickets = 100;
// 定义同一把锁
private Object obj = new Object();
@Override
public void run() {
while (true) {
// t1,t2,t3都能走到这里
// 假设t1抢到CPU的执行权,t1就要进来
// 假设t2抢到CPU的执行权,t2就要进来,发现门是关着的,进不去。所以就等着。
// 门(开,关)
synchronized (obj) { // 发现这里的代码将来是会被锁上的,所以t1进来后,就锁了。(关)
if (tickets > 0) {
try {
Thread.sleep(100); // t1就睡眠了
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+ "正在出售第" + (tickets--) + "张票 ");
//窗口1正在出售第100张票
}
} //t1出来了,然后就开门。(开)
}
}
}
测试类:
public class SellTicketDemo {
public static void main(String[] args) {
// 创建资源对象
SellTicket st = new SellTicket();
// 创建三个线程对象
Thread t1 = new Thread(st, "窗口1");
Thread t2 = new Thread(st, "窗口2");
Thread t3 = new Thread(st, "窗口3");
// 启动线程
t1.start();
t2.start();
t3.start();
}
}
结果:不会出现多个线程同时执行同个共享数据、不会出现卖出0、-1、-2的情况。
java 22 - 12 多线程之解决线程安全问题的实现方式1的更多相关文章
- java 22 - 13 多线程之解决线程安全问题的实现方式2
上一章说了,解决线程安全问题的实现方式1是使用同步代码块 同时也知道了,同步代码块的锁对象是任意对象:(Object obj ; Demo d;)这些都行 那么,现在来说解决线程安全问题的实现方式2 ...
- java 22 - 7 多线程之控制线程的方法
线程休眠(让线程休息一会再运行) public static void sleep(long millis) 在自定义线程类中添加该方法. 更改后,运行测试类,结果就是每执行完一轮,就休息1秒(这里设 ...
- Java之解决线程安全问题的方式三:Lock锁
import java.util.concurrent.locks.ReentrantLock; /** * 解决线程安全问题的方式三:Lock锁 --- JDK5.0新增 * * 1. 面试题:sy ...
- java线程安全问题以及使用synchronized解决线程安全问题的几种方式
一.线程安全问题 1.产生原因 我们使用java多线程的时候,最让我们头疼的莫过于多线程引起的线程安全问题,那么线程安全问题到底是如何产生的呢?究其本质,是因为多条线程操作同一数据的过程中,破坏了数据 ...
- java并发之如何解决线程安全问题
并发(concurrency)一个并不陌生的词,简单来说,就是cpu在同一时刻执行多个任务. 而Java并发则由多线程实现的. 在jvm的世界里,线程就像不相干的平行空间,串行在虚拟机中.(当然这是比 ...
- Lock锁方式解决线程安全问题
在JDK5.0之后新增加了一种更强大的线程同步机制---通过显示定义同步锁来实现线程同步解决线程安全问题.同步锁使用Lock对象充当. java.util.concurrent.locks.lock接 ...
- 静态同步方法和解决线程安全问题_Lock锁
静态的同步方法锁对象是谁?不能是thisthis是创建对象之后产生的,静态方法优先于对象静态方法的锁对象是本类的cLass属性-->class文件对象(反射) 卖票案例出现了线程安全问题 卖出了 ...
- java 22 - 11 多线程之模拟电影院售票口售票
使用多线程实现的第二种方式: 首先创建自定义类 public class SellTicket implements Runnable { // 定义100张票 private int ticket ...
- 解决线程安全问题_同步方法和解决线程安全问题_Lock锁
解决线程安全问题_同步方法 package com.yang.Test.ThreadStudy; import lombok.SneakyThrows; /** * 卖票案例出现了线程安全的问题 * ...
随机推荐
- Atitit.木马病毒强制强行关闭360 360tray.exe的方法
Atitit.木马病毒强制强行关闭360 360tray.exe的方法 1. taskkill /im 进程名称1 2. 用 wmic process where name="进程名称&qu ...
- Base64 Converter
<Window x:Class="Base64Convertor.MainWindow" xmlns="http://schemas.microsoft.com/w ...
- Hibernate3注解[转]
Hibernate3注解 收藏 1.@Entity(name="EntityName") 必须,name为可选,对应数据库中一的个表 2.@Table(name="&qu ...
- 你真的了解UIWindow吗?
一:首先查看一下关于UIWindow的定义 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIWindow : UIView //window的屏幕,默认是 [UISc ...
- 移动Web开发(一)
1.浅谈Web标准 降低开发复杂度,覆盖的技术层面十分广泛,技术标准化. 以HTML为核心,扩展出几个大类的技术标准: a.程序访问: ECMAScript(ES) 3 . ES 5 . ES ham ...
- 【代码笔记】iOS-评分系统(小星星)
一,效果图. 二,工程图. 三,代码. RootViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additi ...
- IOS 杂笔-1(为什么不继承类簇?)
答:首先,类簇是可以继承的,并不是不可以.例如,我们可以选择继承NSSting,但是此时你用你自己设定的类去调用NSSting的一些方法时,会存在无法实现的问题,这是为什么呢. 1.类簇里有很多私有的 ...
- Java中定义Map常量,List常量
一般的方式的使用静态代码块.比如: public final static Map map = new HashMap(); static { map.put("key1", &q ...
- iOS 从Xcode看应用支持横竖屏
要看一个应用是否支持横竖屏,要看Xcode里面的info.plist文件设置才清楚,每一个新建工程都会包含三个支持方式,即Supported interface orientations里面的就是 P ...
- sqlalchemy多表联合查询(join)
使用outerjoin instances = db.session.query(Instance.name, Instance.sep_status, User.email).outerjoin( ...