Java 线程的同步(synchronized)与死锁

本文介绍了Java线程同步的概念,通过卖票问题展示了不同同步情况下可能产生的问题。详细讲解了synchronized关键字的使用,包括同步代码块和同步方法,并分析了死锁现象及其示例。通过同步虽然保障了数据安全性,但可能导致性能下降,过度使用还可能引发死锁。
摘要由CSDN通过智能技术生成

同步的引入

当多个线程并发执行时,线程对数据的访问也是并发执行的,假设有线程A和线程B两个线程,同时会访问数据Data,并且更改数据Data。有可能出现一下两种运行顺序:

  1. 线程A访问Data–>线程A更改Data–>线程B访问Data–>线程B更改Data
  2. 线程A访问Data–>线程B访问Data–>线程A更改Data–>线程B更改Data

情况1运行后,数据正常访问,结果正确;但是如果情况2发生,那么就会出现对同一数值实现两次更改的情况,数据A对Data的更改会失效。
此时产生的问题就是线程不同步引起的。

范例程序:卖票问题

//六个票贩子同时进行售票活动
class MyThread implements Runnable {
   
    private int ticket = 10 ;
    @Override
    public void run() {     
        for (int x = 0 ; x < 20 ; x++ ) {
            if (this.ticket > 0) {
                System.out.println( Thread.currentThread().getName() + ": ticket = " + ticket-- ) ;
            }
        }
    }
}
public class Demo {
   
    public static void main(String args[]) throws Exception{
        MyThread mt = new MyThread() ;
        new Thread(mt,"票贩子A:").start() ;
        new Thread(mt,"票贩子B:").start() ;
        new Thread(mt,"票贩子C:").start() ;
        new Thread(mt,"票贩子D:").start() ;
        new Thread(mt,"票贩子E:").start() ;
        new Thread(mt,"票贩子F:").start() ;
    }
}

输出结果:
票贩子A:: ticket = 9
票贩子A:: ticket = 4
票贩子A:: ticket = 3
票贩子A:: ticket = 2
票贩子A:: ticket = 1
票贩子F:: ticket = 5
票贩子E:: ticket = 6
票贩子D:: ticket = 7
票贩子B:: ticket = 8
票贩子C:: ticket = 10;

如果在售票线程中使用延时:

class MyThread implements Runnable {
    private int ticket = 10 ;
    @Override
    public 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值