线程不安全三大问题_解决 同步方法及同步块
Posted liqiliang1437
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程不安全三大问题_解决 同步方法及同步块相关的知识,希望对你有一定的参考价值。
package com.qiliang.demo13_线程同步安全;
// 线程同步安全问题 , 卖票案例演示
public class UnSafeBuyTicket {
public static void main(String[] args) {
BuyTicket station = new BuyTicket();
new Thread(station,"小A").start();
new Thread(station,"小B").start();
new Thread(station,"黄牛党").start();
}
}
class BuyTicket implements Runnable{
// 定义票数
private int ticketNums = 10;
// 线程停止的标志位
boolean flag = true;
@Override
public void run() {
// 买票
while (flag){
buy();
}
}
// synchronized 同步方法
private synchronized void buy() {
// 判断是否有票
if(ticketNums<=0){
flag = false;
return;
}
// 模拟延时,放大问题的发生性
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 买票
System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);
}
}
// 线程不安全, 有负数
/*
黄牛党拿到10
小B拿到9
小A拿到8
黄牛党拿到7
小B拿到6
小A拿到5
黄牛党拿到4
小B拿到3
小A拿到2
黄牛党拿到1
小B拿到0
小A拿到-1
*/
``` java
package com.qiliang.demo13_线程同步安全;
// 线程同步安全问题,不安全的取钱案例
public class UnSafeBank {
public static void main(String[] args) {
Account account = new Account(1000, "结婚基金");
Drawing xiaoli = new Drawing("小李", account, 50);
Drawing xiaowang = new Drawing("小王", account, 100);
xiaoli.start();
xiaowang.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(String name, Account account, int drawingMoney) {
super(name);
this.account = account;
this.drawingMoney = drawingMoney;
}
// 取钱
@Override
public void run() {
synchronized (account){
// 判断有没有钱
if (account.money-drawingMoney<0) {
System.out.println(Thread.currentThread().getName()
+"钱不够,取不了!");
return;
}
// 模拟延时
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 卡内余额 = 余额 - 你取的钱
account.money = account.money - drawingMoney;
// 你手里的钱
nowMoney = nowMoney + drawingMoney;
System.out.println(account.name+"余额为"+account.money);
// Thread.currentThread().getName() = this.getName()
System.out.println(this.getName()+"手里的钱:"+nowMoney);
}
}
}
``` java
package com.qiliang.demo13_线程同步安全;
import java.util.ArrayList;
// 线程不安全的集合
public class UnSafeList {
public static void main(String[] args) throws InterruptedException {
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
new Thread(()->{
synchronized (list){
list.add(Thread.currentThread().getName());
}
}).start();
}
Thread.sleep(3000); // 9997 i=10000
System.out.println(list.size()); // 918 i=1000
}
}
以上是关于线程不安全三大问题_解决 同步方法及同步块的主要内容,如果未能解决你的问题,请参考以下文章