java多线程实现Runnable接口的线程安全问题

本文通过模拟火车站售票场景探讨多线程中的线程安全问题,分析原因并提出解决方案。介绍了同步代码块、同步方法以及Lock锁三种避免线程安全问题的方法,并比较了synchronized与Lock的异同,建议在实际开发中根据需求选择合适的同步机制。
摘要由CSDN通过智能技术生成

一、案例:模拟火车站售票,开启三个窗口售票

  • 出现的问题:卖票过程中,出现了重票、错票 ==>也就是出现了线程的安全问题
  • 问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票。
  • 解决思路:当一个线程(一个窗口)在操作ticket(火车票)的时候,其他线程不能参与进来。直到这个线程(这个窗口)操作完ticket(火车票)时,其他线程才可以开始操作ticket(火车票)。这种情况即使这个线程(这个窗口)出现了阻塞,也不能被改变。
  • 解决办法:在Java中,我们通过同步机制,来解决线程的安全问题。
    方式一:同步代码块
    方式二:同步方法
    方式三:Lock锁(JDK5.0新增)
  • 同步的方式:
    好处:解决了线程的安全问题。
    局限性:操作同步代码时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低。

例如下方代码就会出现重票、漏票的情况

class Window implements Runnable{
   
    // 定义共有100张票
    private int ticket = 100;
    Object obj = new Object();
    
    @Override
    public void run() {
   
        while(true){
   
        // 如果还有票,就售票
            if (ticket > 0) {
   
				try {
   
                		Thread.sleep(100);
                    } catch (InterruptedException e) {
   
                        e.printStackTrace();
                    }
                System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
                
                ticket --;
            } else {
   
                break;
            }
        }
    }
}


public class WindowTest {
   
    public static void main(String[] args) {
   
        // 创建售票窗口对象
        Window window = new Window();

		// 创建Thread对象
        Thread t1 = new Thread(window );
        Thread t2 = new Thread(window );
        Thread t3 = new Thread(window );

		// 给线程设置线程名称
        t1.setName("窗口1")
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值