买票练习
@Slf4j(topic = "c.ExerciseSell")
public class ExerciseSell {
public static void main(String[] args) throws InterruptedException {
// 模拟多人买票
TicketWindow window = new TicketWindow(1000);
// 所有线程的集合
List threadList = new ArrayList();
// 卖出的票数统计
List amountList = new Vector();
for (int i = 0; i {
// 买票
int amount = window.sell(random(5));
// 统计买票数
amountList.add(amount);
});
threadList.add(thread);
thread.start();
}
for (Thread thread : threadList) {
thread.join();
}
// 统计卖出的票数和剩余票数
log.debug("余票:{}", window.getCount());
log.debug("卖出的票数:{}", amountList.stream().mapToInt(i -> i).sum());
}
// Random 为线程安全
static Random random = new Random();
// 随机 1~5
服务器托管网 public static int random(int amount) {
r服务器托管网eturn random.nextInt(amount) + 1;
}
}
// 售票窗口
class TicketWindow {
//此时 count是共享变量
private int count;
public TicketWindow(int count) {
this.count = count;
}
// 获取余票数量
public int getCount() {
return count;
}
// 售票 加上synchronized 同一时刻只有一个线程可以访问此线程
public synchronized int sell(int amount) {
if (this.count >= amount) {
this.count -= amount;
return amount;
} else {
return 0;
}
}
}
将上面代码的Vector改为ArrayList,是否会出现线程安全问题?
输出如下
22:09:36.690 c.ExerciseSell [main] - 余票:0
Exception in thread "main" java.lang.NullPointerException
at cn.itcast.n4.exercise.ExerciseSell.lambda$main$1(ExerciseSell.java:37)
at java.util.stream.ReferencePipeline$4$1.accept(ReferencePipeline.java:210)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.IntPipeline.reduce(IntPipeline.java:457)
at java.util.stream.IntPipeline.sum(IntPipeline.java:415)
at cn.itcast.n4.exercise.ExerciseSell.main(ExerciseSell.java:37)
由于arrayList并不是线程安全的,多个线程调用add方法会导致线程安全问题
Vector是线程安全的集合所以没有此问题
转账练习
public static void main(String[] args) throws InterruptedException {
//注意有A B两个账户
Account a = new Account(1000);
Account b = new Account(1000);
Thread t1 = new Thread(() -> {
for (int i = 0; i {
for (int i = 0; i = amount) {
this.setMoney(this.getMoney() - amount);
target.setMoney(target.getMoney() + amount);
}
}
}
单个对象使用对象锁,多个对象并发修改的情况下使用类锁
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
摘要:计算机认证考试是评估和验证个人在计算机科学和信息技术领域的专业知识和技能的重要途径。本文将为读者介绍计算机认证考试的重要性,以及为成功通过考试而采取的步骤。 引言: 在当今数字化时代,计算机技术的不断发展使得拥有强大计算机能力的专业人员越来越受追捧。然而…