摸索前进
package iostudy.synchro;
/**
* 多线程并发、同步保证数据准确性,效率尽可能高和好
* 线程安全:
* 1、在并发池保证数据的准确性
* 2、同时保证效率尽可能高
* synchronized
* 1、同步方法
* 2、同步块
* @since JDK 1.8
* @date 2021/6/11
* @author Lucfier
*/
public class SynTestNo1 {
public static void main(String[] args) {
/*创建资源类对象*/
SafeWeb12306 safeWeb12306 = new SafeWeb12306();
/*多个线程*/
new Thread(safeWeb12306, "fe斯特").start();
new Thread(safeWeb12306, "赛肯").start();
new Thread(safeWeb12306, "瑟得").start();
}
}
/**
* 创建一个资源类,测试同步方法
*/
class SafeWeb12306 implements Runnable{
/*票数*/
private int ticketNums = 99;
/*设置开关*/
private boolean flag = true;
/*重写run方法--->多线程执行入口*/
之前出现负数资源的原因
-
最后一位资源为1
-
三个线程同时访问该资源(A,B,C)
-
B线程先运行,但是B不<=0,所以进行延时等待。B没有修改数据
-
此时A和C也进入线程体。此时B刚好修改数据而A和C访问到的资源数还是1
出现线程访问到相同资源数的原因
-
每个线程都有一个工作空间与主存交互
-
线程会round(加载)、store(存储)
-
当B线程没有将工作空间的修改数据返回主存的时候A、C线程也对主存的数据拷贝了一份
-
所以还是原来的资源数而不是更新后的资源数
这样就实现了同步,(线程大概率按顺序访问)
synchronized方法实例
package iostudy.synchro;
/**
* 多线程并发、同步保证数据准确性,效率尽可能高和好
* 线程安全:
* 1、在并发池保证数据的准确性
* 2、同时保证效率尽可能高
* synchronized
* 1、同步方法
* 2、同步块
* @since JDK 1.8
* @date 2021/6/11
* @author Lucfier
*/
public class SynTestNo1 {
public static void main(String[] args) {
/*创建资源类对象*/
SafeWeb12306 safeWeb12306 = new SafeWeb12306();
/*多个线程*/
new Thread(safeWeb12306, "fe斯特").start();
new Thread(safeWeb12306, "赛肯").start();
new Thread(safeWeb12306, "瑟得").start();
}
}
/**
* 创建一个资源类,测试同步方法
*/
class SafeWeb12306 implements Runnable{
/*票数*/
private int ticketNums = 1000;
/*设置开关*/
private boolean flag = true;
/*重写run方法--->多线程执行入口*/
synchronized锁定目标不对(锁定对象不对),导致锁定失败
AccountTest类:
package iostudy.synchro;
/**
* 创建一个账户类--->资源类
* @since JDK 1.8
* @date 2021/6/10
* @author Lucifer
*/
public class AccountTest {
/*定义资源属性*/
int money; //金额
String name; //名称字符串
/*创建构造器*/
public AccountTest(int money, String name) {
this.money = money;
this.name = name;
}
}
锁定错误的线程同步类:
package iostudy.synchro;
public class SynTestNo2 {
/*定义资源属性*/
int money; //金额
String name; //名称字符串
public static void main(String[] args) {
AccountTest accountTest = new AccountTest(100, "money");
SafeDrawing you = new SafeDrawing(accountTest, 80, "Lucifer");
SafeDrawing she = new SafeDrawing(accountTest, 90, "JunkingBoy");
you.start();
she.start();
}
/*创建构造器*/
public SynTestNo2(int money, String name) {
this.money = money;
this.name = name;
}
}
/**
* 模拟提款机提款类--->多线程
* @since JDK 1.8
* @date 2021/6/10
* @author Lucifer
*/
class SafeDrawing extends Thread{
/*创建实现类对象--->面向对象的思想*/
AccountTest accountTest; //取出的账户
int drawingMoney; //取出的钱数
int pocketTotal; //取出的钱的总数
/*创建构造器,将属性定义为参数*/
public SafeDrawing(AccountTest accountTest, int drawingMoney, String name) {
super(name); //线程的名称
this.accountTest = accountTest;
this.drawingMoney = drawingMoney;
}
/*重写run方法--->线程的具体实现*/