首页 > 技术文章 > 线程问题

tangdeqiang 2017-11-03 16:43 原文

在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。这就说明了线程在执行过程中可以执行其他没有被锁的方法和线程,这些点在学习过程中都需要注意。

推荐阅读