线程的同步是指:
在一个多线程环境下保证数据的准确性、安全性--->线程安全
提升性能--->三高原则(高性能、高并发、高可用)
难点:
线程的同步不够形象
并发控制比较困难--->琢磨、分析、又快又好
并发是指:
同一个对象多个线程同时操作--->同一个银行账户取钱
package iostudy.synchro;
?
/**
* 线程不安全的演示
* @since JDK 1.8
* @date 2021/6/10
* @author Lucifer
*/
public class UnsafeTestNo1 {
public static void main(String[] args) {
?
/*实例化实现类对象--->一份资源对象*/
UnsafeWeb12306 unsafeWeb12306 = new UnsafeWeb12306();
?
/*实例化多个代理商--->多个线程*/
new Thread(unsafeWeb12306, "小马哥!").start();
new Thread(unsafeWeb12306, "大马哥!").start();
new Thread(unsafeWeb12306, "老马哥!").start();
/*
1、这样写线程会导致线程不安全,有负数的情况和重复值的情况
2、可能会出现两个99和值-1、-2
*/
?
}
}
?
/**
* 创建一个内部多线程类
*/
class UnsafeWeb12306 implements Runnable{
?
/*设置资源数--->票数*/
private int ticketNums = 99;
/*开关*/
private boolean flag = true;
?
/*重写Runnable接口当中的run方法*/
说明:
这里面涉及到边界值的概念
同一时间片a、b、c三个线程都进入到多线程环境中(没有线程池)
b先进入,持有资源等待
b先拿走资源--->默认用户线程要执行完毕
a、c也需要执行完毕,只能拿走0、-1
关键点是没有控制最后一份资源而jvm默认所有线程不经过设置都是用户线程
new一个新生状态的线程的时候会开辟一个工作空间
每一个线程的工作空间只与主存交互,各线程之间不存在数据交互
在主存数据发生修改之前有两个线程与主存的数据进行交互,同时从主存拷贝值拿到工作空间进行处理导致出现两个一样的值
package iostudy.synchro;
?
/**
* 模拟银行取款线程不安全的情况
* 1、同一账户
* 2、多人同时操作
* 同时取出
* 一边取出一边存入
* 会造成数据的不一致
* @since JDK 1.8
* @date 2021/6/10
* @author Lucifer
*/
public class UnsafeTestNo2 {
public static void main(String[] args) {
/*创建资源类对象*/
Account account = new Account(100, "彩礼");
?
/*两个代理类对象--->三个参数(账户、取出数目、取出的人员*/
Drawing you = new Drawing(account, 80, "你");
Drawing she = new Drawing(account, 90, "她");
?
/*调用start方法--->就绪状态*/
you.start();
she.start();
?
}
}
?
/**
* 创建一个账户类--->资源类
* @since JDK 1.8
* @date 2021/6/10
* @author Lucifer
*/
class Account{
?
/*定义资源属性*/
int money; //金额
String name; //名称字符串
?
/*创建构造器*/
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
?
/**
* 模拟提款机提款类--->多线程
* @since JDK 1.8
* @date 2021/6/10
* @author Lucifer
*/
class Drawing extends Thread{
?
/*创建实现类对象--->面向对象的思想*/
Account account; //取出的账户
int drawingMoney; //取出的钱数
int pocketTotal; //取出的钱的总数
?
/*创建构造器,将属性定义为参数*/
public Drawing(Account account, int drawingMoney, String name) {
super(name); //线程的名称
this.account = account;
this.drawingMoney = drawingMoney;
}
?
/*重写run方法--->线程的具体实现*/