3-1-Java多线程-案例-售票&线程状态

售票案例

线程状态

image

售票的动作需要被多个线程同时执行,所以要使用多线程技术

代码示例-线程不安全

 代码


class Ticket implements Runnable{

    private int tickets = 20;
    /*售票动作需要被多线程执行,那就是线程任务代码*/
    private Object object =  new Object();
    public void run() {
         while (true)
         {
             if (tickets > 0)
             {
                 try {
                     tickets--;
                     Thread.sleep(10);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 System.out.println(Thread.currentThread().getName() +"..........."+ tickets);
             }

             if (tickets<=0)
             {
                 return;
             }
         }
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        /*创建runnable接口的子类对象*/
        Ticket ticket = new Ticket();
        /*创建4个线程对象*/
        Thread t1 = new Thread(ticket);
        Thread t2 = new Thread(ticket);
        Thread t3 = new Thread(ticket);
        Thread t4 = new Thread(ticket);
        /*开启线程*/
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

执行结果

Thread-1...........16
Thread-2...........16
Thread-3...........16
Thread-0...........16
Thread-3...........12
Thread-2...........12
Thread-1...........12
Thread-0...........9
Thread-0...........8
Thread-3...........8
Thread-2...........8
Thread-1...........8
Thread-1...........4
Thread-0...........4
Thread-3...........4
Thread-2...........4
Thread-2...........0
Thread-3...........0
Thread-1...........0
Thread-0...........0

运行结果分析

横向箭头代表CPU切换,竖向箭头代表程序向下执行.

可以看到当判断完票数是否>0后且在执行票数–前发生CPU执行线程的切换(线程进入临时阻塞状态)

image

代码示例-线程安全


class Ticket implements Runnable{

    private int tickets = 20;
    /*售票动作需要被多线程执行,那就是线程任务代码*/
    private Object object =  new Object();
    public void run() {
         while (true)
         {
             /**
              * obj相当于锁
              * 火车上的卫生间,有一个显示牌表示有没有人在用,
              * 如果有人等待,如果无人进去锁门。
              */
             synchronized (object)
             {
                 if (tickets > 0)
                 {
                     try {
                         tickets--;
                         Thread.sleep(10);
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                     System.out.println(Thread.currentThread().getName() +"..........."+ tickets);
                 }
             }

             if (tickets<=0)
             {
                 return;
             }
         }
    }
}
public class ThreadDemo {
    public static void main(String[] args) {
        /*创建runnable接口的子类对象*/
        Ticket ticket = new Ticket();
        /*创建4个线程对象*/
        Thread t1 = new Thread(ticket);
        Thread t2 = new Thread(ticket);
        Thread t3 = new Thread(ticket);
        Thread t4 = new Thread(ticket);
        /*开启线程*/
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

执行结果

Thread-1...........19
Thread-1...........18
Thread-1...........17
Thread-1...........16
Thread-1...........15
Thread-1...........14
Thread-1...........13
Thread-1...........12
Thread-1...........11
Thread-1...........10
Thread-1...........9
Thread-1...........8
Thread-1...........7
Thread-1...........6
Thread-1...........5
Thread-1...........4
Thread-1...........3
Thread-1...........2
Thread-1...........1
Thread-1...........0

线程问题发生的原因

  • 1.多个线程在操作共享的数据
  • 2.线程任务操作共享数据的代码有多条运算

解决方法

  • 只要让一个线程在执行线程任务时,将多条操作共享数据的代码执行完,在执行过程中,不要让其他线程参与运算。

Java实现同步的方法

  • Java中解决此问题是通过代码块来完成的。
  • 这个代码块称为同步代码块syschronized
  • syschronized(){}

同步的前提

  • 必须保证多个线程在同步中使用同一个锁
  • synchronized (new Object())是错误的

同步的好处

  • 解决了多线程的安全性问题

同步的弊端

  • 降低的程序的性能

如何区分同步

  • 同步通过锁来判断是否为同一个同步
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值