激情久久久_欧美视频区_成人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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久亚洲国产精品 | xnxx 日本免费 | 精品视频 久久久 | 久久精品网址 | 国产大片中文字幕在线观看 | 中文字幕亚洲情99在线 | 成人激情综合网 | 羞羞的动漫在线观看 | 成人免费毛片网站 | 精品中文字幕在线播放 | 久久久www成人免费毛片 | 91网址在线观看 | 日韩精品羞羞答答 | 日韩精品羞羞答答 | 在线免费av网站 | 欧美一区二区三区中文字幕 | 黄色网址在线免费播放 | 国产伊人色 | 黄色片免费在线播放 | 国产分类视频 | 99精品国产成人一区二区 | 中国一级毛片在线视频 | 成人国产高清 | 黄色网址免费入口 | 1级片在线观看 | 亚洲影院久久久av天天蜜桃臀 | 国产宾馆3p国语对白 | 精品成人免费一区二区三区 | 26uuu成人人网图片 | 精品久久久久久久久久久久 | 毛片在线免费观看视频 | 久久蜜桃香蕉精品一区二区三区 | 国产91大片| 欧美一区二区三区久久综合 | 一级免费a | 午夜影院在线免费观看 | 欧美日韩在线中文字幕 | 深夜影院a | 色女人在线| 素人视频在线观看免费 | 成人毛片100部免费观看 |