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. 过多的同步有可能造成死锁,死锁是在程序运行时的一种表现状态
发布了6 篇原创文章 · 获赞 0 · 访问量 52
App 阅读领勋章
微信扫码 下载APP
阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 深蓝海洋 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览