国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java編程多線程之共享數據代碼詳解

Java編程多線程之共享數據代碼詳解

2021-04-01 13:35brianway Java教程

這篇文章主要介紹了Java編程多線程之共享數據代碼詳解,分享了相關代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下

本文主要總結線程共享數據的相關知識,主要包括兩方面:一是某個線程內如何共享數據,保證各個線程的數據不交叉;一是多個線程間如何共享數據,保證數據的一致性。

線程范圍內共享數據

 

自己實現的話,是定義一個Map,線程為鍵,數據為值,表中的每一項即是為每個線程準備的數據,這樣在一個線程中數據是一致的。

例子

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.iot.thread;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
 * Created by brian on 2016/2/4.
 */
public class ThreadScopeShareData {
    //準備一個哈希表,為每個線程準備數據
    private static Map<Thread,Integer> threadData = new HashMap<>();
    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();
                    threadData.put(Thread.currentThread(),data);
                    System.out.println(Thread.currentThread()+" put data:"+data);
                    new A().get();
                    new B().get();
                }
            }
            ).start();
        }
    }
    static class A{
        public void get(){
            int data = threadData.get(Thread.currentThread());
            System.out.println("A from "+Thread.currentThread()+" get data "+data);
        }
    }
    static class B{
        public void get(){
            int data = threadData.get(Thread.currentThread());
            System.out.println("B from "+Thread.currentThread()+" get data "+data);
        }
    }
}

上述代碼偶爾會報異常:

Exception in thread "Thread-0" java.lang.NullPointerException
at com.iot.thread.ThreadScopeShareData$A.get(ThreadScopeShareData.java:29)
at com.iot.thread.ThreadScopeShareData$1.run(ThreadScopeShareData.java:21)
at java.lang.Thread.run(Thread.java:745)

具體原因還不知道

ThreadLocal類

 

API:

java.lang:Class ThreadLocal<T>

  • 單變量

使用ThreadLocal類型的對象代替上面的Map即可

  • 多變量

定義一個對象來封裝多個變量,然后在ThreadLocal中存儲整個對象

多變量時,最好將ThreadLocal類放在數據類的內部,數據類采用單例模式,這樣,新建對象和獲取對象都會更方便,同時封裝性更強。

示例代碼:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.iot.thread;
import java.util.Random;
/**
 * Created by brian on 2016/2/4.
 */
public class ThreadLocalTest {
    private static ThreadLocal<Integer> threadInger = 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(100);
                    threadInger.set(data);
                    System.out.println(Thread.currentThread()+" put data:"+data);
                    MyThreadScopeData.getThreadInstance().setName(Thread.currentThread().toString());
                    MyThreadScopeData.getThreadInstance().setAge(data%10);
                    new A().get();
                    new B().get();
                }
            }
            ).start();
        }
    }
    static class A{
        public void get(){
            int data = threadInger.get();
            System.out.println("A from "+Thread.currentThread()+" get data "+data);
            MyThreadScopeData myThreadScopeData = MyThreadScopeData.getThreadInstance();
            System.out.println("A from "+myThreadScopeData);
        }
    }
    static class B{
        public void get(){
            int data = threadInger.get();
            System.out.println("B from "+Thread.currentThread()+" get data "+data);
            MyThreadScopeData myThreadScopeData = MyThreadScopeData.getThreadInstance();
            System.out.println("B from "+myThreadScopeData);
        }
    }
}
/**
 * 將多變量封裝起來的數據類
 * 單例模式,內置ThreadLocal類型變量
 */
class MyThreadScopeData{
    private MyThreadScopeData(){
    }
    private static ThreadLocal<MyThreadScopeData> data = new ThreadLocal<>();
    public static MyThreadScopeData getThreadInstance(){
        MyThreadScopeData instance = data.get();
        if(instance == null){
            instance = new MyThreadScopeData();
            data.set(instance);
        }
        return instance;
    }
    private String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
      public String toString() {
        String reVal = super.toString()+"-{name,age}"+":{"+getName()+","+getAge()+"}";
        return reVal;
    }
}

多線程訪問共享數據

 

幾種方式

  • 線程執行代碼相同,使用同一Runnable對象,Runnable對象中有共享數據
  • 線程執行代碼不同,將共享數據封裝在另一對象中(操作數據的方法也在該對象完成),將這個對象逐一傳遞給各個Runnable對象。[本質:共享數據的對象作為參數傳入Runnable對象]
  • 線程執行代碼不同,將Runnable對象作為某一個類的內部類,共享數據作為這個外部類的成員變量(操作數據的方法放在外部類)。[本質:不同內部類共享外部類數據]
  • 結合上兩種方式,將共享數據封裝在另一對象中(操作數據的方法也在該對象完成),該對象作為這個外部類的成員變量,將Runnable對象作為內部類

最后一種方式的示例:

設計5個線程,其中三個線程每次對j增加1,另外兩個線程對j每次減少1

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.iot.thread;
/**
 * Created by brian on 2016/2/4.
 */
public class MutiThreadShareData {
    private static MutiShareData mutiShareData = new MutiShareData();
    public static void main(String[] args) {
        for (int i=0;i<3;i++){
            new Thread(
                      new Runnable() {
                @Override
                            public void run() {
                    System.out.println(Thread.currentThread()+":{j from "+ mutiShareData.getJ()+" + to: "+mutiShareData.increment()+"}");
                }
            }
            ).start();
        }
        for (int i=0;i<2;i++){
            new Thread(
                      new Runnable() {
                @Override
                            public void run() {
                    System.out.println(Thread.currentThread()+":{j from "+ mutiShareData.getJ()+" - to: "+mutiShareData.decrement()+"}");
                }
            }
            ).start();
        }
    }
}
/**
 * 將共享數據封裝在另一對象中(操作數據的方法也在該對象完成)
 */
class MutiShareData{
    private int j = 0;
    public synchronized int increment(){
        return ++j;
    }
    public synchronized int decrement(){
        return --j;
    }
    public synchronized int getJ() {
        return j;
    }
    public synchronized void setJ(int j) {
        this.j = j;
    }
}

總結

 

以上就是本文關于Java編程多線程之共享數據代碼詳解的全部內容,希望對大家有所幫助。感興趣的朋友可以繼續參閱本站其他相關專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:http://blog.csdn.net/h3243212/article/details/50659415

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久精品亚洲 | 色女人的天堂 | www免费网站在线观看 | 亚洲色图综合 | 日韩欧美在线视频 | 国产精品久久久久久久久久免费看 | 色影视| 午夜大片男女免费观看爽爽爽尤物 | 国产免费高清 | 日韩成人免费在线 | 一本一道久久a久久精品逆3p | 亚洲精品久久久久久动漫 | 国产免费自拍 | 精品综合 | 欧美亚洲综合久久 | 免费视频国产 | 国产成人免费高清激情视频 | 狠狠操网站 | 开心久久婷婷综合中文字幕 | 久久久看片 | 国产亚洲精品久久久久久久久 | 欧美日韩国产一区二区在线观看 | 国产乱码精品一区二区三 | 一区日韩 | 欧美999| 国产精品69毛片高清亚洲 | 亚洲成人精品在线观看 | 国产精品女同一区二区免费站 | 国产在线不卡 | 亚洲视频在线一区 | 国产成人在线视频 | 日韩在线电影 | 国产精品免费视频一区二区三区 | 成人在线小视频 | 国产精品日韩欧美 | 亚洲精品久久久久久下一站 | 亚洲国产精品人人爽夜夜爽 | 天堂久久精品 | 欧美大片一区 | 欧美国产精品一区二区 | 午夜免费剧场 |