教育路上
摘要:java多线程同步,当多个线程去访问同一个资源时,也会引发一些安全问题,java 多线程同步。以下是我们为大家整理的,相信大家阅读完后肯定有了自己的选择吧。
2022-05-19 13:48网络推荐
前面小节讲解过多线程的并发执行可以提高程序的效率,但是,当多个线程去访问同一个资
源时,也会引发一些安全问题。例如,当统计一个班级的学生数目时,如果有同学进进出出,
则很难统计正确。为了解决这样的问题,需要实现多线程的同步,即限制某个资源在同一时
刻只能被一个线程访问。接下来将详细讲解多线程中出现的问题以及如何使用同步来解决。
14.5.1 线程安全
例 14 -5 中的售票案例,极有可能碰到“意外”情况,如一张票被打印多次,或者打印
出票号为 0 甚至负数。这些“意外”都是由多线程操作共享资源 ticket 所导致的线程安全问
题,接下来针对例 5-5 进行修改,模拟四个窗口出售 10 张票,并在售票的代码中使每次售票
时线程休眠 10ms,如例 14-11 所示。
例 14-11 Example11.java
public class Example11 {
public static void main(String[] args) {
SaleThread saleThread = new SaleThread(); // 创建 Ticket1 对象
// 创建并开启四个线程
new Thread(saleThread, "线程一").start();
new Thread(saleThread, "线程二").start();
new Thread(saleThread, "线程三").start();
new Thread(saleThread, "线程四").start();
}
}
// 定义 Ticket1 类实现 Runnable 接口
class SaleThread implements Runnable {
private int tickets = 10; // 10 张票
public void run() {
while (tickets > 0) {
try {
Thread.sleep(10); // 经过此处的线程休眠 10 毫秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "---卖出的票"
+ tickets--);
}
}
}
运行结果如图 14-15 所示
图 14-15 中,最后几行打印售出的票为 0 和负数,这种现象是不应该出现的,因为在售票
程序中做了判断,只有当票号大于 0 时才会进行售票。运行结果中之所以会出现了负数的票
号是因为多线程在售票时出现了安全问题。接下来对问题进行简单的分析。
在售票程序的 while 循环中添加 sleep()方法,这样就模拟了售票过程中线程的延迟。由
于线程的延迟,当票号减为 1 时,假设线程 1 此时出售 1 号票,对票号进行判断后,进入
while 循环,在售票之前通过 sleep( )方法让线程休眠,这时线程二会进行售票,由于此时票
号仍为 1,因此线程二也会进人循环,同理,四个线程都会进入 while 循环,休眠结束后,四个
线程都会进行售票,这样就相当于将票号减了四次,结果中出现了 0、-1、-2 这样的票号。
访客的评论 2023/09/29 20:28
文中描述的是准确的吗,如何报名!