同步和死锁(三)上

简介: 同步和死锁(三)

一. 同步


同步,就是加锁,避免同一个资源访问时会出现的问题。


还是以以前的卖票程序进行举例。


一.一 这是不加同步的


public static void main(String[] args) {
        test5();
    }
    public static void test5(){
        //实例化一次对象
        MyRunnableDemo5 myRunnableDemo1=new MyRunnableDemo5();
        Thread thread1=new Thread(myRunnableDemo1);
        Thread thread2=new Thread(myRunnableDemo1);
        Thread thread3=new Thread(myRunnableDemo1);
        //启动, 三个客户端进行抢票
        thread1.start();
        thread2.start();
        thread3.start();
    }
     static class  MyRunnableDemo5 implements Runnable{
        private int ticket=5;
        @Override
        public void run() {
            for(int i=0;i<10;i++){
                if(ticket>0){
                    //加上一个延时,表示卖票需要耗费时间差。
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("还剩下:"+ticket+"张票");
                    ticket--;
                }
            }
        }
    }


运行程序, 观察控制台, 可能的一种结果


20200619172511616.png


发现,查询的票数是不对的,并且卖出的票数也是不对的。


一.二 加入同步


同步,可以分为两种,一种是同步代码块, 另外一种是同步方法, 用 synchronized 关键字进行修饰。


一.二.一 同步代码块


public static void main(String[] args) {
    //test5();
        test6();
    }
public static void test6(){
        //实例化两次
        MyRunnableDemo6 myRunnableDemo1=new MyRunnableDemo6();
        Thread thread1=new Thread(myRunnableDemo1);
        Thread thread2=new Thread(myRunnableDemo1);
        Thread thread3=new Thread(myRunnableDemo1);
        //启动
        thread1.start();
        thread2.start();
        thread3.start();
    }
    static class MyRunnableDemo6 implements Runnable{
        private int ticket=5;
        @Override
        public void run() {
               for(int i=0;i<10;i++){
        // 进行同步, 同步的是当前对象  
                   synchronized (this){
                       if(ticket>0){
                           try {
                               Thread.sleep(1000);
                           } catch (InterruptedException e) {
                               e.printStackTrace();
                           }
                           System.out.println("还剩下:"+ticket+"张票");
                           ticket--;
                    }
                 }
           }
        }
    }


运行程序,控制台打印输出


20200619172522752.png


查询的票数是对的,卖出的票数也是对的。


一.二.二 同步方法


public static void main(String[] args) {
    //test5();
       // test6();
    test7();
    }
    public static void test7(){
        //实例化两次
        MyRunnableDemo7 myRunnableDemo1=new MyRunnableDemo7();
        Thread thread1=new Thread(myRunnableDemo1);
        Thread thread2=new Thread(myRunnableDemo1);
        Thread thread3=new Thread(myRunnableDemo1);
        //启动
        thread1.start();
        thread2.start();
        thread3.start();
    }
    static class MyRunnableDemo7 implements Runnable{
        private int ticket=5;
        @Override
        public void run() {
      //调用同步方法
            pay();
        }
    //同步方法
        public synchronized void pay(){
            for(int i=0;i<10;i++){
                if(ticket>0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("还剩下:"+ticket+"张票");
                    ticket--;
                }
            }
        }
    }


运行程序,查看控制台信息


20200619172532119.png

相关文章
|
3月前
|
算法 Java 程序员
同步与互斥(二)
同步与互斥(二)
61 0
|
6月前
|
安全
什么是死锁?互斥锁进入死锁怎么解决?
什么是死锁?互斥锁进入死锁怎么解决?
|
缓存 Oracle 关系型数据库
【数据设计与实现】第5章:同步与互斥
同步与互斥设计原则数据库的一个重要能力就是为多个用户提供并发访问服务,并发度是考察数据库性能的重要指标之一。事务隔离级别定义了并发控制算法的正确性,并让用户通过选择隔离级别在正确性和高性能之间进行平衡。事务重点考虑的是数据层面的并发控制,是属于较上层的同步与互斥。实际上,数据库系统是由大量进程、线程、数据结构构成的,进程、线程会并发地访问、修改数据结构,还需要在较底层级解决数据结构的同步与互斥问题
【数据设计与实现】第5章:同步与互斥
|
6月前
|
存储 自然语言处理 算法
【数据结构入门精讲 | 第一篇】打开数据结构之门
【数据结构入门精讲 | 第一篇】打开数据结构之门
78 0
|
搜索推荐 应用服务中间件 Apache
什么是泛目录?二级目录反向代理怎么做?
现在很多人都想做泛目录排名,关于很多新手而言,会觉得泛目录排名是一个高深的技能,事实上只要一个程序就能够完成泛目录排名,那么什么是泛目录?这个问题分红两个部分:
什么是泛目录?二级目录反向代理怎么做?
|
安全
同步和死锁(三)下
同步和死锁(三)
133 0
同步和死锁(三)下
|
SQL Java 数据库连接
MybatisPlus快速入门 1
MybatisPlus快速入门
63 1
|
SQL 关系型数据库 MySQL
使用tkmapper避免更新on update字段
使用tkmapper避免更新on update字段
166 0
|
人工智能 编解码 算法
2023热点持续,站在 ChatGPT 的肩上编程
2023热点持续,站在 ChatGPT 的肩上编程
479 0
2023热点持续,站在 ChatGPT 的肩上编程
|
Java Nacos 开发者
课程管理-删除小节删除视频(服务调用) | 学习笔记
简介:快速学习课程管理-删除小节删除视频(服务调用)
104 0
课程管理-删除小节删除视频(服务调用) | 学习笔记