線程(五)

1.join()方法:等子線程執行完成以後再結束主線程.java

例子:dom

public class MyThread extends Thread{
    @Override
    public void run() {
        try {
            int sec= (int) (Math.random()*10000);
            System.out.println(sec);
            Thread.sleep(sec);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class Test {
    public static void main(String[] args) throws InterruptedException {
        MyThread thread=new MyThread();
        thread.start();
        thread.join();
        System.out.println("我想當thread對象執行完畢後我再執行");
        System.out.println("但上面代碼中的sleep()中的值寫多少呢?");
        System.out.println("答案是不能肯定");
    }
/*
我想當thread對象執行完畢後我再執行
但上面代碼中的sleep()中的值寫多少呢?
答案是不能肯定
9488
*/
}

咱們的目的是先執行子線程再進行打印,解決方法:ide

public class Test {
    public static void main(String[] args) throws InterruptedException {
        MyThread thread=new MyThread();
        thread.start();
        thread.join();
        System.out.println("我想當thread對象執行完畢後我再執行");
    }
/*
5392
我想當thread對象執行完畢後我再執行
*/
}

在join的過程當中若是線程被中斷,則當前線程出現異常this

public class ThreadA extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            String newString=new String("");
            Math.random();
        }
    }
}
public class ThreadB extends Thread{
    @Override
    public void run() {
        try {
            ThreadA a=new ThreadA();
            a.start();
            a.join();
            System.out.println("線程B在end處打印了");
        } catch (InterruptedException e) {
            System.out.println("線程B在catch處打印了");
            e.printStackTrace();
        }
    }
}
public class ThreadC extends Thread{
    private ThreadB threadB;
    public ThreadC(ThreadB threadB){
        super();
        this.threadB=threadB;
    }

    @Override
    public void run() {
        threadB.interrupt();
    }
}
public class Run {
    public static void main(String[] args) throws InterruptedException {
        ThreadB b=new ThreadB();
        b.start();
        Thread.sleep(5000);
        ThreadC c=new ThreadC(b);
        c.start();
    }
/*
java.lang.InterruptedException
    at java.lang.Object.wait(Native Method)
    at java.lang.Thread.join(Thread.java:1258)
    at java.lang.Thread.join(Thread.java:1332)
    at mutithreading.ThreadB.run(ThreadB.java:12)
線程B在catch處打印了
*/
}

join(long)的使用: 只等long秒.線程

ps:join()和synchronized()方法的區別:對象

joind在內部使用wait()方法進行等待,而synchronized關鍵字是使用"對象監視器"原理get

join(long)和sleep(long)的區別it

join的功能是使用wait(long)方法來實現的,因此join(long)具備釋放鎖的特色,sleep不會放鎖io

2.ThreadLocal的使用:class

主要解決的就是每一個線程綁定本身的值,能夠將ThreadLocal類比喻成全局存放數據的盒子,盒子中能夠存放存儲每一個線程的私有數據.

證實ThreadLocal的隔離性:

public class ThreadLocalExt extends ThreadLocal{
    @Override
    protected Object initialValue() {
        return new Date().getTime();
    }
}
public class Tools {
    public static ThreadLocalExt t1=new ThreadLocalExt();
}
public class ThreadA extends Thread{
    @Override
    public void run() {
        try {
            for (int i = 0; i <100 ; i++) {
                Tools.t1.set("ThreadA"+(i+1));
                System.out.println("ThreadA get Value="+Tools.t1.get());
                Thread.sleep(2000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class ThreadB extends Thread{
    @Override
    public void run() {
        try {
            for (int i = 0; i <100 ; i++) {
                Tools.t1.set("ThreadB"+(i+1));
                System.out.println("ThreadB get Value="+Tools.t1.get());
                Thread.sleep(2000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
public class Run {
    public static void main(String[] args) {
        try {
            ThreadA a=new ThreadA();
            ThreadB b=new ThreadB();
            a.start();
            b.start();
            for (int i = 0; i <100 ; i++) {
                Tools.t1.set("Main"+(i+1));
                System.out.println("Main get value="+Tools.t1.get());
                Thread.sleep(2000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
/*ThreadA get Value=ThreadA1
Main get value=Main1
ThreadB get Value=ThreadB1
Main get value=Main2
ThreadA get Value=ThreadA2
ThreadB get Value=ThreadB2
*/
}

總結:3個線程,每一個線程都set而且get到本身的值.

相關文章
相關標籤/搜索