亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Java線程與并發(fā)庫高級應(yīng)用-線程范圍內(nèi)共享數(shù)據(jù)ThreadLocal類

??? 2016-11-07 14:09:18 710
????:1.線程范圍內(nèi)共享變量 1.1 前奏:使用一個Map來實(shí)現(xiàn)線程范圍內(nèi)共享變量 public class ThreadScopeShareData {     static Map<Thread, Integer> dataMap = new HashMap

1.線程范圍內(nèi)共享變量 

1.1 前奏:

使用一個Map來實(shí)現(xiàn)線程范圍內(nèi)共享變量 

public class ThreadScopeShareData {

    static Map<Thread, Integer> dataMap = new HashMap<Thread, Integer>();

    public static void main(String[] args) {
        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    int data = new Random().nextInt(); // 獲取一個隨機(jī)整數(shù)
                    System.out.println(Thread.currentThread().getName()
                            + " put data " + data);
                    dataMap.put(Thread.currentThread(), data);
                    new A().get();
                    new B().get();
                }
            }).start();
        }
    }

    static class A {
        public void get() {
            System.out.println(Thread.currentThread().getName() + " get data "
                    + dataMap.get(Thread.currentThread()));
        }
    }

    static class B {
        public void get() {
            System.out.println(Thread.currentThread().getName() + "get data "
                    + dataMap.get(Thread.currentThread()));
        }
    }

}

1.2 ThreadLocal類實(shí)際上就是一種map

/**
 * ThreadLocal 類 這里ThreadLocal存放一個變量,如果有多個變量, 可以先將多個變量封裝為一個對象
 * 
 * @author Administrator
 * 
 */
public class ThreadLocalTest {
    static ThreadLocal<Integer> x = new ThreadLocal<>(); //

    public static void main(String[] args) { //
        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    int data = new Random().nextInt(); // 獲取一個隨機(jī)整數(shù)
                    System.out.println(Thread.currentThread().getName()
                            + " put data " + data);
                    x.set(data);
                    new A().get();
                    new B().get();
                }
            }).start();
        }
    }

    static class A {
        public void get() {
            System.out.println(Thread.currentThread().getName() + " get data "
                    + x.get());
        }
    }

    static class B {
        public void get() {
            System.out.println(Thread.currentThread().getName() + "get data "
                    + x.get());
        }
    }

}

 2.線程范圍內(nèi)共享多個變量,可以將多個變量封裝為一個對象

/**
 * ThreadLocal 類 這里ThreadLocal存放一個變量,如果有多個變量, 可以先將多個變量封裝為一個對象
 * 
 * @author Administrator
 * 
 */
public class ThreadLocalTest {
    static ThreadLocal<Integer> x = new ThreadLocal<>(); //

    public static void main(String[] args) { //
        for (int i = 0; i < 2; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    int data = new Random().nextInt(); // 獲取一個隨機(jī)整數(shù)
                    System.out.println(Thread.currentThread().getName()
                            + " put data " + data);
                    x.set(data);
                    MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();//獲取與線程綁定的對象
                    myData.setName("name"+data);
                    myData.setAge(data);
                    System.out.println(Thread.currentThread().getName()
                            + " put Object " + "name: "+myData.getName()+","+" age: "+myData.getAge());
                    new A().get();
                    new B().get();
                }
            }).start();
        }
    }

    static class A {
        public void get() {
            System.out.println(Thread.currentThread().getName() + " get data "
                    + x.get());
            MyThreadScopeData instance = MyThreadScopeData.getThreadInstance(); //直接獲取與該線程相關(guān)的對象
            System.out.println(Thread.currentThread().getName() + " get Object "
                    + "name: "+instance.getName()+","+" age: "+instance.getAge());
        }
    }

    static class B {
        public void get() {
            System.out.println(Thread.currentThread().getName() + "get data "
                    + x.get());
            MyThreadScopeData instance = MyThreadScopeData.getThreadInstance(); //直接獲取與該線程相關(guān)的對象
            System.out.println(Thread.currentThread().getName() + " get Object "
                    + "name: "+instance.getName()+","+" age: "+instance.getAge());
        }
    }

}

// 單例
class MyThreadScopeData {  //類的實(shí)例是與線程相關(guān)的,那么類的設(shè)計(jì)就交由類自身完成,只要調(diào)用自然就是與線程有關(guān)的 
    private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<>();

    private MyThreadScopeData() {

    }

    public static MyThreadScopeData getThreadInstance() { // 線程間是相互獨(dú)立的,這里不需要考慮同步
        MyThreadScopeData instance = map.get();
        if (instance == null) {
            instance = new MyThreadScopeData();
            map.set(instance);
        }
        return instance;
    }

    private String name;
    private Integer age;

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * @param age
     *            the age to set
     */
    public void setAge(Integer age) {
        this.age = age;
    }

}

打印結(jié)果

Thread-1 put data -723086824
Thread-0 put data 772514756
Thread-1 put Object name: name-723086824, age: -723086824
Thread-0 put Object name: name772514756, age: 772514756
Thread-0 get data 772514756
Thread-1 get data -723086824
Thread-0 get Object name: name772514756, age: 772514756
Thread-1 get Object name: name-723086824, age: -723086824
Thread-0get data 772514756
Thread-1get data -723086824
Thread-0 get Object name: name772514756, age: 772514756
Thread-1 get Object name: name-723086824, age: -723086824

類的實(shí)例是與線程相關(guān)的,那么類的設(shè)計(jì)就交由類自身完成,只要調(diào)用自然就是與線程有關(guān)的  strust2的主要思想就是這么設(shè)計(jì)的

參看JAVA API

ThreadLocal有一個 remove()方法

可以移除與該線程相關(guān)的變量

remove() 
Removes the current thread's value for this thread-local variable.

補(bǔ)充:

  虛擬機(jī)的對應(yīng)類 Runtime ,中有一個方法 addShutdownHook(Thread hook)

  addShutdownHook(Thread hook) 
  Registers a new virtual-machine shutdown hook.

  例如可以寫一個發(fā)送郵件的線程Thread,當(dāng)虛擬機(jī)掛掉之前會調(diào)用傳入的Thread,發(fā)送一封郵件。

線程中是不是也應(yīng)該有這種機(jī)制,當(dāng)一個線程掛掉之前可以執(zhí)行一個之前注冊好的事件,或者有一個監(jiān)聽器在監(jiān)聽線程的狀態(tài),從而進(jìn)行回調(diào)

在獲取到線程掛掉的通知,就可以把該線程相關(guān)的變量全部remove獲取clear掉



??? ??

?? ??