• JAVA中关于同步与死锁的问题


    java中当多个现成同时操纵同一资源的时候需要考虑同步的问题。如车站售票,不同售票点卖同一班次车票的时候就要同步,否则卖票会有问题。下面代码模拟车站卖票:

    class TicketSeller implements Runnable
    {
        public int ticket = 20;
    
        public void run()
        {
            for(int i = 0; i < 100; i++)
            {
                synchronized(this)
                {
                    if(this.ticket-- >0)
                    {
                        Utilities.sleep(300);
                        System.out.println(Thread.currentThread().getName() + "卖出一张票,余票:" + (this.ticket) + "张");
                    }
                }
            }
        }
    }
    
    
    class Utilities
    {
        public static void sleep(int timeSpan)
        {
            try
            {
                Thread.sleep(timeSpan);
            }
            catch (Exception e)
            {
            }
        }
    }
    
    class Hello
    {
        public static void main(String[] args) 
        {
            TicketSeller ts = new TicketSeller();
            Thread tl = new Thread(ts,"铜梁站");
            Thread bs = new Thread(ts,"璧山站");
            Thread spb = new Thread(ts,"沙坪坝站");
    
            tl.start();
            bs.start();
            spb.start();
        }
    }

    输出结果:

    但有时过多的使用同步会造成程序性能下降。除此之外过多同步还会发生更严重的后果:死锁。

    也就是说,同步代码块中都去争夺同一资源,互不相让。举个例子,在一条东西方向的狭窄的巷道中,AB两车相遇,互补退让,结果是两个车都走不了,这就是死锁。这里隐含了一个情景就是,A车占有东边这一段道路,它需要B车让出B车占有西边的道路,而同时B车占有西边的道路,它需要A车让出A车所占有的西边的道路。两车各自占有各自的资源,且同时争夺对方占有的资源,互补相让,就造成了死锁。

    这里,为了更好的阐述并模拟JAVA中死锁的情况。我再举一个例子:

    小红和小明马上就要毕业了,都在准备毕业论文的撰写。他们的论文都要用到两本书,一本是《汇编语言》,另一本是《算法导论》。他们都要去图书馆借阅这两本书,但图书馆规定某一人一次只能借阅1本书。于是小红借了《汇编原理》,小明借了《算法导论》。过了一段时间后,他们论文都完成了一 半。此时,小红需要小明手中的《算法导论》,同时小明也要小红手中的《汇编原理》。但是小红对小明说:“你先把《算法导论》给我了,我完成论文后就把《汇编原理》给你。” 小明不同意,他对小红说:“你把《汇编原理》先给我,我完成论文后把《算法导论》给你。” 这样,小红和小明各持有一本书,却又要求获得对方的书才交出自己持有的那本书。他们两人互不相让,结果就导致了死锁的发生。

    现在我用JAVA语言对以上场景进行模拟:

    class Book
    {
        public String name;
        public float price;
    
        public Book(String name, float price)
        {
            this.name = name;
            this.price = price;
        }
    }
    
    
    class Student implements Runnable
    {
        private String studentName;
        private   Book book1;
        private   Book book2;
    
        public Student(String studentName,Book book1, Book book2)
        {
            this.book1 = book1;
            this.book2 = book2;
    
            this.studentName = studentName;
        }
    
        public void run()
        {
            synchronized(this.book1)
            {
                System.out.println(this.studentName+"拿到了"+this.book1.name +"开始写论文");
                Utilities.sleep(5000);
                System.out.println(this.studentName+"完成一半需要"+this.book2.name);
                synchronized(this.book2)
                {
                    System.out.println(this.studentName+"拿到了"+this.book2.name +"继续写论文");
                }
                System.out.println(this.studentName+"完成了论文");
            }
            
        }
    } 
    
    
    class Utilities
    {
        public static void sleep(int timeSpan)
        {
            try
            {
                Thread.sleep(timeSpan);
            }
            catch (Exception e)
            {
                System.out.println(e);
            }
        }
    }
    
    class Hello
    {
        public static void main(String[] args) 
        {
            Book book1 = new Book("汇编原理",23.5f);
            Book book2 = new Book("算法导论",85.5f);
    
            Thread xh = new Thread(new Student("小红",book1,book2));
            Thread xm = new Thread(new Student("小明",book2,book1));
            xh.start();
            xm.start();
        }
    }

    输出结果:

    上图显示,程序一直卡在这个地方,不会往下执行。这就是死锁。

  • 相关阅读:
    oracle触发器
    oracle存储函数
    ****Java程序调用存储过程****
    oracle储存过程--存储过程
    oracle储存过程--游标
    oracle存储过程--流程控制(条件判断和循环遍历)
    InterviewProblems
    RandomAccessFile浅析
    JSP基础——关于中文乱码问题
    基础数据结构——单链表
  • 原文地址:https://www.cnblogs.com/kuillldan/p/5574954.html
Copyright © 2020-2023  润新知