欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java实现死锁的两种实现以及无限调用的synchronized

程序员文章站 2022-03-29 19:25:26
...

目录

1.显示定义一个线程的方法

代码逻辑:

代码展示:

运行结果:

2.显示定义两个线程的方法:原理同第一个

代码逻辑:

代码展示:

运行结果:

3.synchronized实现的无限循环的demo

代码逻辑:

代码展示:

运行结果:


现在这个模式:存在什么样的问题:
我们都是demo:但是却对的方法没有研究,没有感觉

解决:死锁的不同的原理的demo:

1.显示定义一个线程的方法

代码逻辑:

多线程死锁的本质:
* 和synchronized 中的new object类似
* 直接new object1 object2
* <p>
* thread1 :lock(1) ---> thread.sleep() ----->lock(2)
* thread2 :lock(2) ---> thread.sleep() ----->lock(1)
* p>
* 同时多个线程要达到同时启动的效果,且会根据区分执行以上的流程:
* 如果在一个线程方法里面,需要一个 flag
* 否则就需要多个线程逻辑,(这个时候如果需要共用object,那么可以内部类实现!)
* <p>

代码展示:

package com.special.thread.javamulthreadbook;

import com.sun.org.apache.bcel.internal.generic.NEW;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;

/**
 * @author liuYC
 * @ClassName DeadLockDemo2
 * @Description TODO
 * @date 2021/7/22 16:27
 * <p>
 * 多线程死锁的本质:
 * 和synchronized 中的new object类似
 * 直接new object1 object2
 * <p>
 * thread1 :lock(1) ---> thread.sleep() ----->lock(2)
 * thread2 :lock(2) ---> thread.sleep() ----->lock(1)
 * p>
 * 同时多个线程要达到同时启动的效果,且会根据区分执行以上的流程:
 * 如果在一个线程方法里面,需要一个 flag
 * 否则就需要多个线程逻辑,(这个时候如果需要共用object,那么可以内部类实现!)
 * <p>
 * 为什么验证的时候,输出的结果总是没有死锁了:
 * name = a
 * name = b
 * execute lock2 ------> lock1
 * execute lock1 ------> lock2
 * name = b
 * execute lock2 ------> lock1
 */
public class DeadLockDemo2 {
    //    @SneakyThrows
    public static void main(String[] args) {
        DeadThread deadThread = new DeadThread();
        deadThread.setFlag("a");
        Thread thread1 = new Thread(deadThread);
        thread1.start();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        deadThread.setFlag("b");
        Thread thread2 = new Thread(deadThread);
        thread2.start();

        /*deadThread.setFlag("b");
        Thread thread2 = new Thread(deadThread);
        thread2.start();*/
    }
}

class DeadThread implements Runnable {
    public Object object1 = new Object();
    public Object object2 = new Object();
    public String name;

    public void setFlag(String name) {
        this.name = name;
    }

    //    @SneakyThrows
    @Override
    public void run() {

        if (StringUtils.equals(name, "a")) {
            synchronized (object1) {
                System.out.println("name = " + name);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (object2) {
                System.out.println("execute lock1 ------> lock2");
            }
        }
        if (StringUtils.equals(name, "b")) {
            synchronized (object2) {
                System.out.println("name = " + name);
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            synchronized (object1) {
                System.out.println("execute lock2 ------> lock1");
            }
        }
    }
}

运行结果:

* name = a
* name = b
* execute lock2 ------> lock1
* execute lock1 ------> lock2
* name = b
* execute lock2 ------> lock1

2.显示定义两个线程的方法:原理同第一个

代码逻辑:

同第一个,只不过是两个线程的定义的实现方法:

代码展示:

https://blog.csdn.net/jasonkwan12/article/details/80050607?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162694477816780269863657%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=162694477816780269863657&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~baidu_landing_v2~default-6-80050607.first_rank_v2_pc_rank_v29&utm_term=%E6%AD%BB%E9%94%81Java%E5%AE%9E%E7%8E%B0&spm=1018.2226.3001.4187

参考文章

运行结果:


3.synchronized实现的无限循环的demo

代码逻辑:

* 的代码证明: 无限等待方法的解决
* 本质就是new object
* synchronized()代码块的时候,锁的对象是不同的对象实例
*

代码展示:

package com.special.thread.javamulthreadbook;

import javax.swing.text.StyledEditorKit;

/**
 * @author liuYC
 * @ClassName DeadlockDemo1
 * @Description TODO
 * @date 2021/7/22 15:27
 * <p>
 * 的代码证明: 无限等待方法的解决
 * 本质就是new object
 * synchronized()代码块的时候,锁的对象是不同的对象实例
 *
 * 案例,
 * 单线程和多线程的区别,注意
 */
public class DeadlockDemo1 {
    public static void main(String[] args) {
        final DeadService deadService = new DeadService();
        final DeadThreadA deadThreadA = new DeadThreadA(deadService);
        final DeadThreadB deadThreadB = new DeadThreadB(deadService);
        deadThreadA.start();
        deadThreadB.start();
    }
}


class DeadThreadA extends Thread {
    private DeadService deadService;

    public DeadThreadA(DeadService deadService) {
        this.deadService = deadService;
    }

    @Override
    public void run() {
        super.run();
        deadService.deadMethodA();
    }
}

class DeadThreadB extends Thread {
    private DeadService deadService;

    //构造方法,初始化传入目标对象,进行返回的调用
    public DeadThreadB(DeadService deadService) {
        this.deadService = deadService;
    }

    @Override
    public void run() {
        super.run();
        deadService.deadMethodB();
    }
}

class DeadService {
    //    method a 会造成死锁
    public void deadMethodA() {
        System.out.println("=========thread A begin========");
        boolean flag = true;
        while (flag) {
        }
        System.out.println("=========thread A end========");
    }
//    method b正常的方法!

    public void deadMethodB() {
        System.out.println("=========thread B begin========");
        System.out.println("=========thread B end========");

    }

}

运行结果:

=========thread B begin========
=========thread B end========
=========thread A begin========
结论可以看到没有显示:thread a end

解决方法也很简单:

        两个方法里面,锁住代码块的方法

相关标签: 多线程