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

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

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

服務器之家 - 編程語言 - Java教程 - Java線程同步方法實例總結

Java線程同步方法實例總結

2021-05-28 13:08喜歡特別冷的冬天下著雪 Java教程

這篇文章主要介紹了Java線程同步方法,結合實例形式總結分析了Java線程同步、并發控制相關實現方法及操作注意事項,需要的朋友可以參考下

本文實例講述了java線程同步方法。分享給大家供大家參考,具體如下:

1. semaphore

 

1.1 二進制semaphore

semaphore算是比較高級點的線程同步工具了,在許多其他語言里也有類似的實現。semaphore有一個最大的好處就是在初始化時,可以顯式的控制并發數。其內部維護這一個c計數器,當計數器小于等于0時,是不允許其他線程訪問并發區域的,反之則可以,因此,若將并發數設置為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
import java.util.concurrent.semaphore;
public class program{
    public static void main(string[] agrs){
        printqueue p=new printqueue();
        thread[] ths=new thread[10];
        for(int i=0;i<10;i++){
            ths[i]=new thread(new job(p),"thread"+i);
        }
        for(int i=0;i<10;i++){
            ths[i].start();
        }
    }
}
class printqueue{
    private semaphore s;
    public printqueue(){
        s=new semaphore(1);//二進制信號量
    }
    public void printjob(object document){
        try{
            s.acquire();
            long duration=(long)(math.random()*100);
            system.out.printf("線程名:%s 睡眠:%d",thread.currentthread().getname(),duration);
            thread.sleep(duration);
        }
        catch(interruptedexception e){
            e.printstacktrace();
        }
        finally{
            s.release();
        }
    }
}
class job implements runnable{
    private printqueue p;
    public job(printqueue p){
        this.p=p;
    }
    @override
    public void run(){
        system.out.printf("%s:正在打印一個任務\n ",thread.currentthread().getname());
        this.p.printjob(new object());
        system.out.printf("%s:文件已打印完畢\n ",thread.currentthread().getname());
    }
}

執行結果如下:

 thread0:正在打印一個任務
 thread9:正在打印一個任務
 thread8:正在打印一個任務
 thread7:正在打印一個任務
 thread6:正在打印一個任務
 thread5:正在打印一個任務
 thread4:正在打印一個任務
 thread3:正在打印一個任務
 thread2:正在打印一個任務
 thread1:正在打印一個任務
 線程名:thread0 睡眠:32  thread0:文件已打印完畢
 線程名:thread9 睡眠:44  thread9:文件已打印完畢
 線程名:thread8 睡眠:45  thread8:文件已打印完畢
 線程名:thread7 睡眠:65  thread7:文件已打印完畢
 線程名:thread6 睡眠:12  thread6:文件已打印完畢
 線程名:thread5 睡眠:72  thread5:文件已打印完畢
 線程名:thread4 睡眠:98  thread4:文件已打印完畢
 線程名:thread3 睡眠:58  thread3:文件已打印完畢
 線程名:thread2 睡眠:24  thread2:文件已打印完畢
 線程名:thread1 睡眠:93  thread1:文件已打印完畢

可以看到,所有線程提交打印申請后,按照并發順序一次執行,沒有任何并發沖突,誰先獲得信號量,誰就先執行,其他剩余線程均等待。這里面還有一個公平信號與非公平信號之說:基本上java所有的多線程工具都支持初始化的時候指定一個布爾變量,true時表明公平,即所有處于等待的線程被篩選的條件為“誰等的時間長就選誰進行執行”,有點first in first out的感覺,而false時則表明不公平(默認是不non-fairness),即所有處于等待的線程被篩選執行是隨機的。這也就是為什么多線程往往執行順序比較混亂的原因。

1.2 多重并發控制

若將上面的代碼改為s=new semaphore(3);//即讓其每次可以并發3條線程,則輸出如下:

thread0:正在打印一個任務
 thread9:正在打印一個任務
 thread8:正在打印一個任務
 thread7:正在打印一個任務
 thread6:正在打印一個任務
 thread5:正在打印一個任務
 thread3:正在打印一個任務
 thread4:正在打印一個任務
 thread2:正在打印一個任務
 thread1:正在打印一個任務
 線程名:thread9 睡眠:26線程名:thread8 睡眠:46線程名:thread0 睡眠:79  thread9:文件已打印完畢
 線程名:thread7 睡眠:35  thread8:文件已打印完畢
 線程名:thread6 睡眠:90  thread7:文件已打印完畢
 線程名:thread5 睡眠:40  thread0:文件已打印完畢
 線程名:thread3 睡眠:84  thread5:文件已打印完畢
 線程名:thread4 睡眠:13  thread4:文件已打印完畢
 線程名:thread2 睡眠:77  thread6:文件已打印完畢
 線程名:thread1 睡眠:12  thread1:文件已打印完畢
   thread3:文件已打印完畢
   thread2:文件已打印完畢

很明顯已經并發沖突了。若要實現分組(每組3個)并發嗎,則每一組也要進行同步,代碼修改如下:

?
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
import java.util.concurrent.semaphore;
import java.util.concurrent.locks.lock;
import java.util.concurrent.locks.reentrantlock;
public class program{
    public static void main(string[] agrs){
        printqueue p=new printqueue();
        thread[] ths=new thread[10];
        for(int i=0;i<10;i++){
            ths[i]=new thread(new job(p),"thread"+i);
        }
        for(int i=0;i<10;i++){
            ths[i].start();
        }
    }
}
class printqueue{
    private semaphore s;
    private boolean[] freeprinters;
    private lock lock;
    public printqueue(){
        s=new semaphore(3);//二進制信號量
        freeprinters=new boolean[3];
        for(int i=0;i<3;i++){
            freeprinters[i]=true;
        }
        lock=new reentrantlock();
    }
    public void printjob(object document){
        try{
            s.acquire();
            int printerindex=getindex();
                long duration=(long)(math.random()*100);
                system.out.printf("線程名:%s 睡眠:%d\n",thread.currentthread().getname(),duration);
                thread.sleep(duration);
                freeprinters[printerindex]=true;//恢復信號,供下次使用
        }
        catch(interruptedexception e){
            e.printstacktrace();
        }
        finally{
            s.release();
        }
    }
    //返回一個內部分組后的同步索引
    public int getindex(){
        int index=-1;
        try{
            lock.lock();
            for(int i=0;i<freeprinters.length;i++){
                if(freeprinters[i]){
                    freeprinters[i]=false;
                    index=i;
                    break;
                }
            }
     }
     catch(exception e){
         e.printstacktrace();
     }
     finally{
         lock.unlock();
     }
     return index;
    }
}
class job implements runnable{
    private printqueue p;
    public job(printqueue p){
        this.p=p;
    }
    @override
    public void run(){
        system.out.printf("%s:正在打印一個任務\n ",thread.currentthread().getname());
        this.p.printjob(new object());
        system.out.printf(" %s:文件已打印完畢\n ",thread.currentthread().getname());
    }
}

其中getindex()方法主要為了維護內部分組后(支持并發3個)組內數據的同步(用lock來同步)。

輸出如下:

 thread0:正在打印一個任務
 thread9:正在打印一個任務
 thread8:正在打印一個任務
 thread7:正在打印一個任務
 thread6:正在打印一個任務
 thread5:正在打印一個任務
 thread4:正在打印一個任務
 thread3:正在打印一個任務
 thread2:正在打印一個任務
 thread1:正在打印一個任務
 線程名:thread0 睡眠:82  打印機:0號
線程名:thread8 睡眠:61  打印機:2號
線程名:thread9 睡眠:19  打印機:1號
  thread9:文件已打印完畢
 線程名:thread7 睡眠:82  打印機:1號
  thread8:文件已打印完畢
 線程名:thread6 睡眠:26  打印機:2號
  thread0:文件已打印完畢
 線程名:thread5 睡眠:31  打印機:0號
  thread6:文件已打印完畢
 線程名:thread4 睡眠:44  打印機:2號
  thread7:文件已打印完畢
 線程名:thread3 睡眠:54  打印機:1號
  thread5:文件已打印完畢
 線程名:thread2 睡眠:48  打印機:0號
  thread4:文件已打印完畢
 線程名:thread1 睡眠:34  打印機:2號
  thread3:文件已打印完畢
   thread2:文件已打印完畢
   thread1:文件已打印完畢

2. countdownlatch

 

countdownlatch同樣也是支持多任務并發的一個工具。它主要用于“等待多個并發事件”,它內部也有一個計數器,當調用await()方法時,線程處于等待狀態,只有當內部計數器為0時才繼續(countdown()方法來減少計數),也就說,假若有一個需求是這樣的:主線程等待所有子線程都到達某一條件時才執行,那么只需要主線程await,然后在啟動每個子線程的時候進行countdown操作。下面模擬了一個開會的例子,只有當所有人員都到齊了,會議才能開始。

?
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
import java.util.concurrent.countdownlatch;
public class program{
    public static void main(string[] agrs){
        //開啟可容納10人的會議室
        videoconference v=new videoconference(10);
        new thread(v).start();
        //參與人員陸續進場
        for(int i=0;i<10;i++){
            participant p=new participant(i+"號人員",v);
            new thread(p).start();
        }
    }
}
class videoconference implements runnable{
    private countdownlatch controller;
    public videoconference(int num){
        controller=new countdownlatch(num);
    }
    public void arrive(string name){
        system.out.printf("%s 已經到達!\n",name);
        controller.countdown();
        system.out.printf("還需要等 %d 個成員!\n",controller.getcount());
    }
    @override
    public void run(){
        try{
            system.out.printf("會議正在初始化...!\n");
            controller.await();
            system.out.printf("所有人都到齊了,開會吧!\n");
        }
        catch(interruptedexception e){
            e.printstacktrace();
        }
    }
}
class participant implements runnable{
    private videoconference conference;
    private string name;
    public participant(string name,videoconference conference){
        this.name=name;
        this.conference=conference;
    }
    @override
    public void run(){
        long duration=(long)(math.random()*100);
        try{
            thread.sleep(duration);
            conference.arrive(this.name);
     }
     catch(interruptedexception e){
     }
    }
}

輸出:

會議正在初始化...!
0號人員 已經到達!
還需要等 9 個成員!
1號人員 已經到達!
還需要等 8 個成員!
9號人員 已經到達!
還需要等 7 個成員!
4號人員 已經到達!
還需要等 6 個成員!
8號人員 已經到達!
還需要等 5 個成員!
5號人員 已經到達!
還需要等 4 個成員!
6號人員 已經到達!
還需要等 3 個成員!
3號人員 已經到達!
還需要等 2 個成員!
7號人員 已經到達!
還需要等 1 個成員!
2號人員 已經到達!
還需要等 0 個成員!
所有人都到齊了,開會吧!

3. phaser

 

?
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import java.util.concurrent.phaser;
import java.util.concurrent.timeunit;
import java.util.list;
import java.util.arraylist;
import java.io.file;
import java.util.date;
public class program{
    public static void main(string[] agrs){
        phaser phaser=new phaser(3);
        filesearch system=new filesearch("c:\\windows", "log",phaser);
        filesearch apps=new filesearch("c:\\program files","log",phaser);
        filesearch documents=new filesearch("c:\\documents and settings","log",phaser);
        thread systemthread=new thread(system,"system");
        systemthread.start();
        thread appsthread=new thread(apps,"apps");
        appsthread.start();
        thread documentsthread=new thread(documents, "documents");
        documentsthread.start();
        try {
            systemthread.join();
            appsthread.join();
            documentsthread.join();
            } catch (interruptedexception e) {
            e.printstacktrace();
        }
        system.out.println("terminated: "+ phaser.isterminated());
    }
}
class filesearch implements runnable{
    private string initpath;
    private string end;
    private list<string> results;
    private phaser phaser;
    public filesearch(string initpath,string end,phaser phaser){
        this.initpath=initpath;
        this.end=end;
        this.results=new arraylist<string>();
        this.phaser=phaser;
    }
    private void directoryprocess(file file){
        file[] files=file.listfiles();
        if(files!=null){
            for(int i=0;i<files.length;i++){
                if(files[i].isdirectory()){
                    directoryprocess(files[i]);
                }
                else{
                    fileprocess(files[i]);
                }
            }
        }
    }
    private void fileprocess(file file){
        if(file.getname().endswith(end)){
            results.add(file.getabsolutepath());
        }
    }
    private void filterresults(){
        list<string> newresults=new arraylist<string>();
        long actualdate=new date().gettime();
        for(int i=0;i<results.size();i++){
            file file=new file(results.get(i));
            long filedate=file.lastmodified();
            if(actualdate-filedate<timeunit.milliseconds.convert(1,timeunit.days)){
                newresults.add(results.get(i));
            }
        }
        results=newresults;
    }
    private boolean checkresults(){
        if(results.isempty()){
            system.out.printf("%s: phase %d: 0 results.\n",thread.currentthread().getname(),phaser.getphase());
            system.out.printf("%s: phase %d: end.\n",thread.currentthread().getname(),phaser.getphase());
            phaser.arriveandderegister();
        }
        else{
            system.out.printf("%s: phase %d: %d results.\n",thread.currentthread().getname(),phaser.getphase(),results.size());
             phaser.arriveandawaitadvance();
            return true;
        }
    }
    private void showinfo() {
        for (int i=0; i<results.size(); i++){
            file file=new file(results.get(i));
            system.out.printf("%s: %s\n",thread.currentthread().getname(),file.getabsolutepath());
        }
        phaser.arriveandawaitadvance();
    }
    @override
    public void run(){
        file file=new file(initpath);
        if(file.isdirectory()){
            directoryprocess(file);
        }
        if(!checkresults()){
            return;
        }
        filterresults();
        if(!checkresults()){
            return;
        }
        showinfo();
        phaser.arriveandderegister();
        system.out.printf("%s: work completed.\n",thread.currentthread().getname());
    }
}

運行結果:

apps: phase 0: 4 results.
system: phase 0: 27 results.

希望本文所述對大家java程序設計有所幫助。

原文鏈接:https://blog.csdn.net/kkkkkxiaofei/article/details/19079259

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 五月天一区二区 | 三级av在线 | 国产综合精品一区二区三区 | 国产精品久久久久久久久久久久久 | 成人免费黄色毛片 | 欧美日韩成人在线观看 | 黄色一级毛片在线观看 | 中文字幕 在线观看 | 天天干天天躁 | 国产成人精品久久二区二区 | 亚洲免费视频观看 | 欧美日韩第一页 | 精品久久久久一区二区国产 | 免费黄色小视频 | 婷婷精品久久久久久久久久不卡 | 亚洲综合区 | 高清一区二区三区 | 欧美久久精品一级黑人c片 成人在线视频免费观看 | www.中文字幕 | 丁香伊人| 国产精品 日韩 | 久久3| 日本精品免费 | 激情五月婷婷基地 | 综合久| 亚洲欧美一区二区三区久久 | 欧美日韩亚洲成人 | 欧美 日韩 综合 | 国产在线精品一区二区 | 粉嫩一区二区三区 | 欧美3区 | 一区二区三区在线观看视频 | 亚洲精品成a人ⅴ香蕉片 | 91精品麻豆日日躁夜夜躁 | 三级黄色片在线免费观看 | 成人羞羞网站 | 久久久精品影院 | 精品国产在| 成人综合在线观看 | 99久久免费看精品国产 | 久久久精品一区二区 |