Java多线程-----售票问题

本文详细探讨了Java中实现多线程处理售票问题的两种方式:一是通过实现Runnable接口,二是继承Thread类。在实现过程中,重点讨论了遇到的锁相关问题,包括锁的对象必须为同一对象以及正确锁定的范围。文章分别展示了同步代码块、同步方法和对象互斥锁的使用,并给出了每种方式的运行结果。
摘要由CSDN通过智能技术生成

一.实现Runnable接口方式

首先是过程中碰到的问题,出现问题的原因和解决办法:

问题 描述 原因 解决方法
1 同一张票被多次卖出 一个线程打印了卖出第1000张,还没执行ticket - -,另一个线程就进来执行打印卖出第1000张票。 加锁
2 卖出第负数张票 最后一张票卖出时,ticket的值变为0,但此时其他的线程已经在循环内,它们在ticket=0之前就已经等在while循环内、锁区外了,所以ticket=0后它们还会继续各执行一次锁区内的代码,也就会打印出负数了。 在锁区内执行打印之前判断ticket的值。
3 个别线程未打印“票已卖完” while(ticket > 0)把个别线程挡在了外面,无法执行到打印“票已卖完”。 while(ticket > 0)改为while(true),在打印“票已卖完”后用break退出循环。

主要考虑的两个问题:
1.----注意锁的对象:必须要是同一个对象
2.----注意锁的范围:不需要锁的不要锁

锁的分类

1.同步代码块
2.同步方法
3.对象互斥锁

代码

package com.qf.a_task;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 售票
 * @author Zhouzilong
 * @date 2019年8月13日
 */
public class TaskTest {
    public static void main(String[] args) {
        //五个线程操作一个任务对象,若循环中是new Thread(new Task());则是每个线程分别操作一个任务对象,相当于卖5倍数量的票
        Task task = new Task();
        for (int i = 1; i <= 5; i++) {
            new Thread(task,"窗口00"+i).start();
        }
    }
}

class Task implements Runnable{
    private int ticket = 10;
    //实例化互斥对象锁
    private Lock lock = new ReentrantLock();
    
    //方式3:对象互斥锁 ---容易出现死锁
    /*@Override
    public void run() {
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值