1. 程式人生 > >Java 中Thread的sleep、join方法解析

Java 中Thread的sleep、join方法解析

開始 system sleep main gen 解析 等待時間 calling trace

1.Thread中sleep方法作用是使當前線程等待,其他線程開始執行,如果有線程鎖,sleep不會讓出鎖

沒有加鎖代碼如下:

public class SynchronizedSleepMethod {
    public static void main(String[] args) {
        MoneyMethod moneyMethod = new MoneyMethod();
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(new MyThread4(moneyMethod), "t1" + i);
            t.start();
        }
        
for (int i = 0; i < 10; i++) { Thread t = new Thread(new MyThread5(moneyMethod), "t2" + i); t.start(); } } } class MyThread4 implements Runnable { MoneyMethod moneyMethod; /** * */ public MyThread4(MoneyMethod moneyMethod) { // TODO Auto-generated constructor stub
this.moneyMethod = moneyMethod; } /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ @Override public void run() { try { Thread.sleep(1000); moneyMethod.addMoney(); } catch (InterruptedException e) { // TODO Auto-generated catch block
e.printStackTrace(); } } } class MyThread5 implements Runnable { MoneyMethod moneyMethod; /** * */ public MyThread5(MoneyMethod moneyMethod) { // TODO Auto-generated constructor stub this.moneyMethod = moneyMethod; } /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ @Override public void run() { try { Thread.sleep(1000); moneyMethod.subMoney(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // System.out.println(moneyMethod.money); // TODO Auto-generated method stub } } class MoneyMethod { int money = 200; public void addMoney() throws InterruptedException { System.out.println(Thread.currentThread().getName() + ":::run:::" + money); money++; } public void subMoney() throws InterruptedException { System.out.println(Thread.currentThread().getName() + ":::run:::" + money); money--; } }

結果如下:

t10:::run:::202
t12:::run:::202
t11:::run:::202
t13:::run:::203
t15:::run:::205
t14:::run:::204
t17:::run:::207
t19:::run:::209
t18:::run:::209
t16:::run:::207
t21:::run:::207
t24:::run:::205
t22:::run:::206
t20:::run:::206
t29:::run:::203
t28:::run:::203
t26:::run:::202
t27:::run:::201
t23:::run:::200
t25:::run:::199

加鎖代碼如下:

public class SynchronizedSleepMethod {
    public static void main(String[] args) {
        MoneyMethod moneyMethod = new MoneyMethod();
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(new MyThread4(moneyMethod), "t1" + i);
            t.start();
        }
        for (int i = 0; i < 10; i++) {
            Thread t = new Thread(new MyThread5(moneyMethod), "t2" + i);
            t.start();
        }
    }

}

class MyThread4 implements Runnable {
    MoneyMethod moneyMethod;

    /**
     * 
     */
    public MyThread4(MoneyMethod moneyMethod) {
        // TODO Auto-generated constructor stub
        this.moneyMethod = moneyMethod;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            moneyMethod.addMoney();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

class MyThread5 implements Runnable {
    MoneyMethod moneyMethod;

    /**
     * 
     */
    public MyThread5(MoneyMethod moneyMethod) {
        // TODO Auto-generated constructor stub
        this.moneyMethod = moneyMethod;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            moneyMethod.subMoney();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
//        System.out.println(moneyMethod.money);
        // TODO Auto-generated method stub

    }

}

class MoneyMethod {
    int money = 200;

    public synchronized void addMoney() throws InterruptedException {
        money++;
        System.out.println(Thread.currentThread().getName() + ":::run:::" + money);
    }

    public synchronized void subMoney() throws InterruptedException {
        money--;
        System.out.println(Thread.currentThread().getName() + ":::run:::" + money);
    }

}

結果如下:

t10:::run:::201
t18:::run:::202
t17:::run:::203
t12:::run:::204
t13:::run:::205
t14:::run:::206
t15:::run:::207
t16:::run:::208
t11:::run:::209
t19:::run:::210
t22:::run:::209
t21:::run:::208
t20:::run:::207
t25:::run:::206
t24:::run:::205
t23:::run:::204
t26:::run:::203
t27:::run:::202
t29:::run:::201
t28:::run:::200

2.Thread中join()方法阻塞調用此方法的線程(calling thread),直到線程t完成,此線程再繼續;

沒有join()方法代碼如下:

public class JoinMethod {
    public static void main(String[] args) throws InterruptedException {
        MoneyMethod2 moneyMethod = new MoneyMethod2();
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new MyThread4(moneyMethod), "t1" + i);
            t.start();
//            t.join(300);
            System.out.println(Thread.currentThread().getName() + ":::run:::1"+i);
        }
        
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new MyThread5(moneyMethod), "t2" + i);
            t.start();
//            t.join(300);
            System.out.println(Thread.currentThread().getName() + ":::run:::2"+i);
        }
        System.out.println(Thread.currentThread().getName() + ":::finish:::");
    }
}

class MyThread4 implements Runnable {
    MoneyMethod2 moneyMethod;

    /**
     * 
     */
    public MyThread4(MoneyMethod2 moneyMethod) {
        // TODO Auto-generated constructor stub
        this.moneyMethod = moneyMethod;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            Thread.sleep(2000);
            moneyMethod.addMoney();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

class MyThread5 implements Runnable {
    MoneyMethod2 moneyMethod;

    /**
     * 
     */
    public MyThread5(MoneyMethod2 moneyMethod) {
        // TODO Auto-generated constructor stub
        this.moneyMethod = moneyMethod;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            Thread.sleep(2000);
            moneyMethod.subMoney();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
//        System.out.println(moneyMethod.money);
        // TODO Auto-generated method stub

    }

}

class MoneyMethod2 {
    int money = 200;

    public void addMoney() throws InterruptedException {
        money++;
        System.out.println(Thread.currentThread().getName() + ":::add:::" + money);
    }

    public void subMoney() throws InterruptedException {
        money--;
        System.out.println(Thread.currentThread().getName() + ":::sub:::" + money);
    }

}

結果:主線程會提前走掉,然後子線程執行

main:::run:::10
main:::run:::11
main:::run:::12
main:::run:::13
main:::run:::14
main:::run:::20
main:::run:::21
main:::run:::22
main:::run:::23
main:::run:::24
main:::finish:::
t10:::add:::201
t12:::add:::202
t11:::add:::203
t13:::add:::204
t14:::add:::205
t21:::sub:::203
t20:::sub:::203
t24:::sub:::201
t22:::sub:::200
t23:::sub:::201

添加了join後,join的等待時間>線程執行時間,代碼如下:

public class JoinMethod {
    public static void main(String[] args) throws InterruptedException {
        MoneyMethod2 moneyMethod = new MoneyMethod2();
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new MyThread4(moneyMethod), "t1" + i);
            t.start();
            t.join(3000);
            System.out.println(Thread.currentThread().getName() + ":::run:::1"+i);
        }
        
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new MyThread5(moneyMethod), "t2" + i);
            t.start();
            t.join(3000);
            System.out.println(Thread.currentThread().getName() + ":::run:::2"+i);
        }
        System.out.println(Thread.currentThread().getName() + ":::finish:::");
    }
}

class MyThread4 implements Runnable {
    MoneyMethod2 moneyMethod;

    /**
     * 
     */
    public MyThread4(MoneyMethod2 moneyMethod) {
        // TODO Auto-generated constructor stub
        this.moneyMethod = moneyMethod;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            Thread.sleep(2000);
            moneyMethod.addMoney();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

class MyThread5 implements Runnable {
    MoneyMethod2 moneyMethod;

    /**
     * 
     */
    public MyThread5(MoneyMethod2 moneyMethod) {
        // TODO Auto-generated constructor stub
        this.moneyMethod = moneyMethod;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            Thread.sleep(2000);
            moneyMethod.subMoney();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
//        System.out.println(moneyMethod.money);
        // TODO Auto-generated method stub

    }

}

class MoneyMethod2 {
    int money = 200;

    public void addMoney() throws InterruptedException {
        money++;
        System.out.println(Thread.currentThread().getName() + ":::add:::" + money);
    }

    public void subMoney() throws InterruptedException {
        money--;
        System.out.println(Thread.currentThread().getName() + ":::sub:::" + money);
    }

}

結果如下:

t10:::add:::201
main:::run:::10
t11:::add:::202
main:::run:::11
t12:::add:::203
main:::run:::12
t13:::add:::204
main:::run:::13
t14:::add:::205
main:::run:::14
t20:::sub:::204
main:::run:::20
t21:::sub:::203
main:::run:::21
t22:::sub:::202
main:::run:::22
t23:::sub:::201
main:::run:::23
t24:::sub:::200
main:::run:::24
main:::finish:::

加入join方法後,線程執行時間>join的等待時間時,代碼如下:

public class JoinMethod {
    public static void main(String[] args) throws InterruptedException {
        MoneyMethod2 moneyMethod = new MoneyMethod2();
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new MyThread4(moneyMethod), "t1" + i);
            t.start();
            t.join(300);
            System.out.println(Thread.currentThread().getName() + ":::run:::1"+i);
        }
        
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new MyThread5(moneyMethod), "t2" + i);
            t.start();
            t.join(300);
            System.out.println(Thread.currentThread().getName() + ":::run:::2"+i);
        }
        System.out.println(Thread.currentThread().getName() + ":::finish:::");
    }
}

class MyThread4 implements Runnable {
    MoneyMethod2 moneyMethod;

    /**
     * 
     */
    public MyThread4(MoneyMethod2 moneyMethod) {
        // TODO Auto-generated constructor stub
        this.moneyMethod = moneyMethod;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            Thread.sleep(2000);
            moneyMethod.addMoney();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

class MyThread5 implements Runnable {
    MoneyMethod2 moneyMethod;

    /**
     * 
     */
    public MyThread5(MoneyMethod2 moneyMethod) {
        // TODO Auto-generated constructor stub
        this.moneyMethod = moneyMethod;
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
        try {
            Thread.sleep(2000);
            moneyMethod.subMoney();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
//        System.out.println(moneyMethod.money);
        // TODO Auto-generated method stub

    }

}

class MoneyMethod2 {
    int money = 200;

    public void addMoney() throws InterruptedException {
        money++;
        System.out.println(Thread.currentThread().getName() + ":::add:::" + money);
    }

    public void subMoney() throws InterruptedException {
        money--;
        System.out.println(Thread.currentThread().getName() + ":::sub:::" + money);
    }

}

結果如下:

main:::run:::10
main:::run:::11
main:::run:::12
main:::run:::13
main:::run:::14
main:::run:::20
t10:::add:::201
main:::run:::21
t11:::add:::202
main:::run:::22
t12:::add:::203
main:::run:::23
t13:::add:::204
main:::run:::24
main:::finish:::
t14:::add:::205
t20:::sub:::204
t21:::sub:::203
t22:::sub:::202
t23:::sub:::201
t24:::sub:::200

在以上代碼中可以發現,在加入join()方法後主線程還是會提前走,但是所有子線程會按照執行順序執行

Java 中Thread的sleep、join方法解析