多线程: 线程的生命周期及死锁的解决方法

线程的生命周期分为以下几种情况

1:当创建一个线程的时候: New的状态

2:执行start: 就绪状态,这个时候还没有运行,需要分配CPU的资源才能运行

3: 运行状态: 该线程被调度了分配到了CPU资源

4:如果一切正常,线程里的代码执行完,销毁状态(Terminated);

4.1: 如果在运行时执行了wait()这个时候就进入了等待状态,但是这个状态即会释放CPU执行权,如果有锁也会释放锁

4.2: 如果在运行时执行了sleep(1000),进入等待超时状态 这个状态只会释放CPU执行权,不会释放锁

4.3: 如果在运行时执行了yelid(), 或者CPU执行权被抢了,这个时候又会回到第二个状态,就绪.

4.5: 如果线程处在4.2状态,这个时候执行interrupt方法,这个时候就会进入到2的状态也就是就绪状态

4.5: 如果线程处在4.1状态,这个时候执行notify或者notifyAll,线程会进入到2的状态也就是就绪状态

4.6:如果线程中需要获取synchronized锁,进入到阻塞状态,获取到了锁进入到就绪状态.

4.7:如果线程处在4.2状态,等时间到,这个时候会进入到2的状态也就是就绪状态

 

Java发生死锁的条件

1: 多个线程(Thread)操作多个资源(Resource)  Thread要大于Resource 而且它们要>=2

2: 争夺资源的顺序不对.

3: 拿到了资源死不放手.

举个例子

    public static void diedLocd(){
        Object one = new Object();
        Object two = new Object();

        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (one){
                    System.out.println("get one");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (two){
                        System.out.println("get two");
                    }
                }
            }
        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (two){
                    System.out.println("get two");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (one){
                        System.out.println("get onw");
                    }
                }
            }
        }).start();
    }

上面这种情况肯定死锁,

解决方法 :

1: 上面是争夺资源顺序不对,把第一个锁都换成one 第二个变成two肯定不会

2: 上面死锁是一直拿到锁不释放,我们可以采用Lock里的tryLock方法,但是为了避免活锁,最好做一个小点的延时

代码如下

    public static void unDiedLocd() {
        Lock one = new ReentrantLock();
        Lock two = new ReentrantLock();
        Random random = new Random();
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (one.tryLock()) {
                        System.out.println("get one");

                        try {
                            if (two.tryLock()) {
                                try {
                                    System.out.println("get two");
                                    break;
                                } finally {
                                    two.unlock();
                                }
                            }
                        } finally {
                            one.unlock();
                        }
                    }
                    try {
                        Thread.sleep(random.nextInt(3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();


        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (two.tryLock()) {
                        System.out.println("get one");

                        try {
                            if (one.tryLock()) {
                                try {
                                    System.out.println("get two");
                                    break;
                                } finally {
                                    one.unlock();
                                }
                            }
                        } finally {
                            two.unlock();
                        }
                    }
                    try {
                        Thread.sleep(random.nextInt(3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            }
        }).start();
    }

 

你可能感兴趣的:(Java,面试)