zoukankan      html  css  js  c++  java
  • java线程死锁研究

    线程死锁:

           a线程锁定了1号资源,下一步需要锁定2号资源。

           b线程锁定了2号资源,下一步需要锁定1号资源。

           两个线程无限制的等待下去,于是就出现了死锁。

    引用网上的实例:

         

    package test;
    
    public class TestDeadLock extends Thread {
    	static Object o1 = new Object(), o2 = new Object();
    	int flag = 0;
    	public void run() {
    		if(flag == 0){
    			synchronized (o1) {
    				System.out.println("a锁定了刀,想要叉");
    				try {
    					this.sleep(500);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				synchronized (o2){
    					System.out.println("a 要叉成功");
    				}
    			}
    		}
    		if(flag == 1){
    			synchronized (o2) {
    				System.out.println("b锁定了叉,想要刀");
    				try {
    					this.sleep(500);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				synchronized (o1){
    					System.out.println("b 要刀成功");
    				}
    			}
    		}
    	}
    	public static void main(String[] args) {
    		TestDeadLock tdl1 = new TestDeadLock();
    		TestDeadLock tdl2 = new TestDeadLock();
    		tdl1.flag = 0;
    		tdl2.flag = 1;
    		tdl1.start();
    		tdl2.start();
    	}
    }
    

    避免死锁的方法:

            1.让所有的线程按照同样的顺序获得一组锁。这种方法消除了a和b的拥有者分别等待对方的资源的问题。

            2.将多个锁组成一组并放到同一个锁下。前面Java线程死锁的例子中,可以创建一个银器对象的锁。于是在获得刀或叉之前都必须获得这个银器的锁。

            3.将那些不会阻塞的可获得资源用变量标志出来。当某个线程获得银器对象的锁时,就可以通过检查变量来判断是否整个银器集合中的对象锁都可获得。如果是,它就可以获得相关的锁,否则,就要释放掉银器这个锁并稍后再尝试。

    修改方法1:

    package test;
    
    public class TestDeadLock extends Thread {
    	static Object o1 = new Object(), o2 = new Object();
    	int flag = 0;
    	String threadName;
    	public TestDeadLock(String threadName){
    		this.threadName = threadName;
    		
    	}
    	/**
    	 * 把两个方法合并到一个同步块中
    	 */
    	public synchronized void getCanju(){
    		System.out.println(threadName+"锁定了刀,想要叉");
    		try {
    			this.sleep(500);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		System.out.println(threadName+"要叉成功");
    		
    	}
    	public void run() {
    	
    			getCanju();
    
    
    	}
    	public static void main(String[] args) {
    		TestDeadLock tdl1 = new TestDeadLock("线程1");
    		TestDeadLock tdl2 = new TestDeadLock("线程2");
    		tdl1.start();
    		tdl2.start();
    	}
    }
    


  • 相关阅读:
    Oracle不常用SQL
    C# xml 读xml、写xml、Xpath、Xml to Linq、xml添加节点 xml修改节点
    Oracle常见错误:ORA-06550、ORA-00911、ORA-02085
    IIS设置允许跨域
    npm和yarn 切换为国内镜像(淘宝镜像)
    Wordpress 所有 hook 钩子
    【C#】WPF多线程登录需求中报错 “调用线程无法访问对象,因为另一个线程拥有该对象“
    【C#】 WPF 中WebBrowser拖动来移动窗口,改变窗口位置
    【Java】Hibernate一级缓存测试分析
    javac编译单文件、多文件引入jar包、-cp解决无法加载主类问题
  • 原文地址:https://www.cnblogs.com/bestdata/p/3199794.html
Copyright © 2011-2022 走看看