线程第十课——死锁及其解决办法

  这节课我们来讲讲死锁 及其解决办法,这节课讲完我们的线程入门部分就讲完了

  当然,这只是入个门而已,各位有兴趣的话可以去了解自学下juc

 

  OK,废话不多说,写代码

 

死锁问题的产生:

public class DeadLockTeach {



    public static void main(String[] args) {



        Object goods = new Object();

        Object money = new Object();



        Thread thread1 = new Thread1(goods,money,"线程1");

        Thread thread2 = new Thread2(goods,money,"线程2");



        thread1.start();

        thread2.start();



        /**

         * 嗯? 怎么什么都不输出?而且程序并没有结束运行,为什么会这个样子?

         *

         * 大家设想一下,有两个人在进行交易,一个人手里有钱,一个人手里有货

         * 有钱的那人喊"一手交货,一手交钱"

         * 有货的那人喊"一手交钱,一手交货"

         * 两人都希望对方先给自己,担忧不愿意先给对方 ,这样这场交易是不是就永无止境的停滞不前且无法结束?

         *

         * 这就是死锁:

         *   死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,

         *   若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁线程。

         *  

         * 简单点说:

         *   就是现在有两个资源R1,R2

         *   两个线程T1,T2

         *   T1锁着R1要R2,T2锁着R2要R1,但双方都不愿意主动释放锁,最后就造成了死锁

         */

    }



    static class Thread1 extends Thread{

        Object goods;

        Object money;



        public Thread1(Object goods, Object money, String name)

        {

            this.goods = goods;

            this.money = money;

            setName(name);

        }



        @Override

        public void run() {

            while (true)

            {

                //一手交钱

                synchronized (money)

                {

                    try {

                        Thread.sleep(200);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }



                    synchronized (goods)

                    {

                        try {

                            Thread.sleep(200);

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

                        System.out.println("一手交钱,一手交货");

                    }

                }

            }



        }





    }



    static class Thread2 extends Thread{

        Object goods;

        Object money;



        public Thread2(Object goods, Object money, String name)

        {

            this.goods = goods;

            this.money = money;

            setName(name);

        }



        @Override

        public void run() {

            while (true)

            {

                //一手交货

                synchronized (goods)

                {

                    try {

                        Thread.sleep(200);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }



                    //一手交钱

                    synchronized (money)

                    {

                        try {

                            Thread.sleep(200);

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

                        System.out.println("一手交货,一手交钱");

                    }

                }

            }



        }





    }

}

 

解决办法:

生产者-消费者模式 信号灯法

 

/**

 * 生产者-消费者模式

 */

public class ProducerConsumerModel {



    /**

     * 大家设想一个场景:

     * 行人和机动车都要过马路,

     * 机动车过马路的时候人肯定不能走

     * 人走的时候机动车必须停着

     * 而控制是人走还是机动车走就需要一个红绿灯(信号灯)

     * 这就是信号灯法

     */



    public static void main(String[] args) {

        Movie movie = new Movie();

        Actor actor = new Actor(movie);

        Audience audience =  new Audience(movie);

        actor.setMovieName("《正义联盟》");



        actor.start();

        audience.start();



        /**

         * ?????!!!

         * 为啥只有演员拍。观众不能看?

         *

         * 现在就是正常拍,正常看啦

         */

    }



    static class Movie{

        public String name;



        //电影是否拍摄完成

        public boolean finished;



        //拍摄

        void make(String name)

        {

            this.name = name;

            finished = true;

        }



        public String getName() {

            return name;

        }



        //播放

        void play()

        {

            System.out.println("电影" + name + "正在放映");



            //放完了就拍新的

            finished = false;

        }



        public boolean isFinished() {

            return finished;

        }

    }



    //演员

    static class Actor extends Thread{

        Movie movie;

        String movieName;



        public Actor(Movie movie){

            this.movie = movie;

        }



        //用于被告知要拍哪部电影

        public void setMovieName(String movieName) {

            this.movieName = movieName;

        }



        @Override

        public void run() {

            while (true)

            {

                synchronized (movie)

                {

                    //演员来拍电影

                    if (movie.isFinished())

                    {

                        try {

                            //拍完了就等着,等观众老爷看完了再拍

                            movie.wait();

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

                    }

                    else

                    {

                        movie.notify();

                    }

                    try {

                        //要拍5秒

                        Thread.sleep(5000);

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                    movie.make(movieName);

                    System.out.println(movie.getName() + "电影拍完啦");

                    //拍完电影也要放开锁

                    try {

                        movie.wait();

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                }

            }



        }

    }



    //观众

    static class Audience extends Thread{

        Movie movie;



        public Audience(Movie movie)

        {

            this.movie = movie;

        }

        @Override

        public void run() {

            while (true)

            {

                synchronized (movie)

                {



                    if (!movie.isFinished())

                    {

                        //没拍完不让看,等着

                        try {

                            movie.wait();

                        } catch (InterruptedException e) {

                            e.printStackTrace();

                        }

                    }

                    else

                    {

                        movie.notify();

                    }

                    try {

                        Thread.sleep(200);

                        movie.play();

                        System.out.println(movie.getName() + "这部电影真好看");

                        //wait会释放锁,sleep不会释放锁

                        //看完电影就把锁放开

                        movie.wait();

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }



                }

            }

        }

    }

}

你可能感兴趣的:(Java学习)