• Java中的死锁问题


    死锁问题:

      例如有两个线程, 线程1与线程2. 

      线程1在执行的过程中, 要锁定对象1, 2才能完成整个操作, 首先锁定对象1, 再锁定对象2.

      线程2在执行的过程中, 要锁定对象2, 1才能完成整个操作, 首先锁定对象2, 再锁定对象1.

      某时刻, 线程1已经拥有对象1的锁, 要是再拥有对象2的锁就能完成整个操作, 可惜了, 你等待着的对象2的锁已经被别人拥有了, 执行不下去了.

      此时刻, 线程2已经拥有对象2的锁, 要是再拥有对象1的锁就能完成整个操作, 可惜了, 你等待着的对象1的锁已经被别人拥有了, 执行不下去了.

      两个对象都已经锁了, 腰都要求对象放锁, 不可能, 那就都等着吧............

    死锁例程:

    public class DeadLock implements Runnable{
    	public int flag ;
    	static Object o1 = new Object();
    	static Object o2 = new Object();
    	@Override
    	public void run() {
    		System.out.println("flag: "+flag);
    		if(flag == 1) {
    			synchronized(o1){
    				try {
    					Thread.sleep(500);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    			synchronized(o2){
    				System.out.println("1");
    			}
    		}
    		if(flag == 0){
    			synchronized(o2){
    				try {
    					Thread.sleep(500);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    			synchronized(o1){
    				System.out.println("0");
    			}
    		}
    	}
    	public static void main(String[] args) {
    		DeadLock de1 = new DeadLock();
    		DeadLock de2 = new DeadLock();
    		de1.flag = 1;
    		de2.flag = 0;
    		Thread t1 = new Thread(de1);
    		Thread t2 = new Thread(de2);
    		t1.start();
    		t2.start();
    	}
    }
    

     Demo_1:

    public class TT1 implements Runnable {
    	public int b;
    	public synchronized void m1() throws Exception { // 只是方法锁定而已, 别的线程无法执行它
    		b = 1000;                                    // 其他的线程无法再调用它(方法里面的东西(语句))
    		Thread.sleep(5000);
    		System.out.println("b = "+b);
    	}
    	public void m2() {
    		System.out.println(b);
    	}
    	@Override
    	public void run() {
    		try {
    			m1();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	public static void main(String[] args) throws Exception{
    		TT1 tt1 = new TT1();
    		Thread t = new Thread(tt1);
    		t.start();
    		Thread.sleep(1000);
    		tt1.m2();
    	}
    }
    

     运行结果:

    1000
    b = 1000

    Demo_2:

    public class TT2 implements Runnable {
    	public int b = 100;
    	public synchronized void m1() throws Exception { // 互斥, 在某一时刻, 保证只有一个线程进入我们这个方法里面
    		b = 1000;                                    // 但是, 不保证其他的线程是不是能够进入到另外一个方法里面
    		Thread.sleep(5000);
    		System.out.println("b = "+b);
    	}
    	public void m2() throws Exception {
    		Thread.sleep(2500);
    		b = 2000;
    	}
    	@Override
    	public void run() {
    		try {
    			m1();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	public static void main(String[] args) throws Exception{
    		TT2 tt = new TT2();
    		Thread t = new Thread(tt);
    		t.start();
    		tt.m2();
    	}
    }
    

     运行结果:

    b = 2000

      在Demo_2中, 如果在 m2() 的方法也加 synchronized. 同时在主方法中的 tt.m2() 后面加一句: System.out.println(tt.b);

    则, 运行结果为:

    1000

    b = 1000 // 这句话执行得比较快.

    【注】:当某个对象调用了同步方法时, 该对象上的其它同步方法必须等待该同步方法执行完毕后, 才能被执行.

    【注】:其实, 写一个同步的东西是挺困难的. 因为每一个方法要不要同步, 你要考虑得非常清楚.如果一个方法

        做了同步, 另外一个方法没有做同步, 那么你要记住一点: 别的线程可以自由得访问那个非同步的方法,

        并且可能会对你那个同步的方法产生影响, 所以你要保护好某一个类里面的某一个对象的话, 或者说你

        要保护好需要同步的那个对象的话, 你必须对访问这个对象的所有方法仔细考虑, 加不加同步, 加了同

        步, 很有可能效率很低, 不加同步, 有可能产生数据不一致的现象.

  • 相关阅读:
    【已解决】github中git push origin master出错:error: failed to push some refs to
    好记心不如烂笔头,ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题
    THINKPHP 5.0目录结构
    thinkphp5.0入口文件
    thinkphp5.0 生命周期
    thinkphp5.0 架构
    Django template
    Django queryset
    Django model
    Python unittest
  • 原文地址:https://www.cnblogs.com/bosongokay/p/6863281.html
Copyright © 2020-2023  润新知