在Java中 ,学习到java最重要的一个知识点就是线程问题,线程问题是一个比较难以理解的问题,在线程中的死锁问题也是比较经典的·,写一个死锁的线程问题是java工程师经常遇到的面试题,下面给出一个简单的死锁程序,有一个比较经典的死锁问题就是哲学家吃饭问题,因为这个问题就是线程死锁的经典问题,对于喜欢这个问题的人可以上网查询一下学学,下面举个简单的线程死锁问题的程序,方便里理解线程的死锁。
public class TestDeadLock implements Runnable { public int flag = 1; static Object o1 = new Object(), o2 = new Object(); public void run() { System.out.println("flag=" + flag); if(flag == 1) { synchronized(o1) { try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } synchronized(o2) { System.out.println("1"); } } } if(flag == 0) { synchronized(o2) { try { Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } synchronized(o1) { System.out.println("0"); } } } } public static void main(String[] args) { TestDeadLock td1 = new TestDeadLock(); TestDeadLock td2 = new TestDeadLock(); td1.flag = 1; td2.flag = 0; Thread t1 = new Thread(td1); Thread t2 = new Thread(td2); t1.start(); t2.start(); } }
对于这段程序来说,首先用flag来区分线程1和线程2,new了两个对象,所以在这两个对象调用的是同一个run方法,在run方法中用flag来区分不同的线程,当flag=1时,此时线程锁住o1,如果在执行o2(锁住O2)就能打印数字1。当flag=0时,首先锁住o2,如果在锁住o1就能打印数字0。但是结果并不是这样的,因为在执行run方法时,flag=1时把o1锁住不放,所以flag=0不能执行o1,同样flag=0时不能执行o2,导致死锁,所以程序不执行,出现死锁现象,这就是线程的死锁。对于线程除了死锁,还有在锁线程过程中出现的问题,比如看下面的例子
package com.tangdeqiang.rtbc1; public class TT implements Runnable { int b=100; public synchronized void m1() throws Exception{ b=1000; Thread.sleep(5000); System.out.println("b="+b); } public void m2(){ System.out.println(b); } public void run(){ try{ m1(); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[]args) throws Exception{ TT tt=new TT(); Thread t=new Thread(tt); t.start(); Thread.sleep(1000); tt.m2(); } }
这个例子说明线程在执行过程中,虽然线程被锁住,但是线程在执行过程中可以执行其他的方法,如果在线程执行过程中不能执行其他的方法,那么得出的结果就是b=100。但是打印出的结果却是b=1000。这就说明了线程在执行过程中可以执行其他没有被锁的方法和线程,这些点在学习过程中都需要注意。