java线程的同步与死锁

java线程的同步与死锁

问题产生

public class thraedlock {

    public static void main(String[] args) {
        MyThread mt = new MyThread();
        Thread t1 = new Thread(mt,"窗口A");
        Thread t2 = new Thread(mt,"窗口B");
        Thread t3 = new Thread(mt,"窗口C");
        t1.start();
        t2.start();
        t3.start();

    }
}

class MyThread implements Runnable{

    int  ticket = 10;
    @Override
    public void run() {
        for(int i = 0;i<10;i++){
            if(ticket>0){
                try {
                    Thread.sleep(100);
                }catch(InterruptedException e){}
                System.out.println(Thread.currentThread().getName()+"  余票"+ticket--  +"  购票成功");
            }
        }
    }
}

  • 输出
窗口B  余票9  购票成功
窗口A  余票10  购票成功
窗口C  余票10  购票成功
窗口C  余票8  购票成功
窗口A  余票8  购票成功
窗口B  余票8  购票成功
窗口A  余票6  购票成功
窗口B  余票7  购票成功
窗口C  余票7  购票成功
窗口C  余票4  购票成功
窗口A  余票4  购票成功
窗口B  余票5  购票成功
窗口C  余票3  购票成功
窗口B  余票3  购票成功
窗口A  余票2  购票成功
窗口A  余票0  购票成功
窗口B  余票1  购票成功
窗口C  余票-1  购票成功
  • 发现一个一张票被可以被买多次

  • 分析原因 : 三个线程之间共享ticket资源,由于有延时存在,可能会发生多个线程对同一张ticket操作,从而发生一票多卖的情况

解决方法1

  • 使用synchronized同步代码块

  • 语法

    synchronized (同步对象){
        需要同步的代码
    }
    //往往使用this 作为同步对象
    

加入同步后的代码

class MyThread implements Runnable{

    int  ticket = 10;
    @Override
    public void run() {
        for(int i = 0;i<10;i++){
           synchronized(this){
               if(ticket>0){
                   try {
                       Thread.sleep(100);
                   }catch(InterruptedException e){}
                   System.out.println(Thread.currentThread().getName()+"  余票"+ticket--  +"  购票成功");
               }
           }
        }
    }
}

  • 结果

    窗口A  余票10  购票成功
    窗口A  余票9  购票成功
    窗口A  余票8  购票成功
    窗口A  余票7  购票成功
    窗口A  余票6  购票成功
    窗口A  余票5  购票成功
    窗口A  余票4  购票成功
    窗口A  余票3  购票成功
    窗口A  余票2  购票成功
    窗口A  余票1  购票成功
    
  • 运行结果没有错误,但是运行的效率很低

解决方法2

  • 使用同步方法

同步方法声明public synchronized void sale()

class MyThread implements Runnable{

    int  ticket = 10;
    @Override
    public void run() {
        for(int i = 0;i<10;i++){
           sale();
        }
    }
    
    //使用同步方法
    public synchronized  void sale(){
        if(ticket>0){
            try {
                Thread.sleep(100);
            }catch(InterruptedException e){}
            System.out.println(Thread.currentThread().getName()+"  余票"+ticket--  +"  购票成功");
        }
    }
}

死锁

资源共享时需要进行同步操作,但是程序中过多的同步会产生死锁

  • 死锁的含义 : 发生互相等待的情况就叫做死锁

总结

  1. 多线程访问同一资源时,需要进行同步操作
  2. 同步使用synchronized的关键字完成分为同步代码块和同步方法
  3. 过多的同步有可能造成死锁,死锁是在程序运行时的一种表现状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值