多線程協調實例

用好多線程重要的是協調線程調用資源,下面看一個實例:多線程

三個線程,第一個線程循環輸出三條信息,第二個線程循環輸出兩條信息,第三個線程循環輸出一條信息,按照一二三線程順序依次輸出,而後按照這個順序循環五回。ide

 多線程依次輸出,依次控制就是多線程須要訪問的共享資源。this

public class ThreadTest {

    public static class ChildRun implements Runnable {

        private ThreadTest thread;
        
        public ChildRun(ThreadTest thread) {
            this.thread = thread;
        }
        
        @Override
        public void run() {
            for (int i = 0; i < 5; i ++) {
                thread.showChild();
            }
        }
        
    }
    
    public static class GrandsonRun implements Runnable {

        private ThreadTest thread;
        
        public GrandsonRun(ThreadTest thread) {
            this.thread = thread;
        }
        
        @Override
        public void run() {
            for (int i = 0; i < 5; i ++) {
                thread.showGrandson();
            }
        }
        
    }
    
    private int status = 0;
    
    public synchronized void showParent() {
        if (0 != this.status) {
            try {
                this.wait();
                if (0 != this.status) {
                    this.showParent();
                    return ;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        for (int i = 0; i < 3; i ++) {
            System.out.println("parent");
        }
        
        this.notifyAll();
        this.status = 1;
    }
    
    public synchronized void showChild() {
        if (1 != this.status) {
            try {
                this.wait();
                if (1 != this.status) {
                    this.showChild();
                    return ;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        for (int i = 0; i < 2; i ++) {
            System.out.println("child");
            
        }
        
        this.notifyAll();
        this.status = 2;
    }
    
    public synchronized void showGrandson() {
        if (2 != this.status) {
            try {
                this.wait();
                if (2 != this.status) {
                    this.showGrandson();
                    return ;
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        for (int i = 0; i < 1; i ++) {
            System.out.println("grandson");
            
        }
        
        this.notifyAll();
        this.status = 0;
    }
    
    public static void main(String[] args) {
        ThreadTest thread = new ThreadTest();
        ExecutorService service = Executors.newCachedThreadPool();
        
        service.execute(new ChildRun(thread));
        service.execute(new GrandsonRun(thread));
        service.shutdown();
        
        for (int i = 0; i < 5; i ++) {
            thread.showParent();
        }
    }

}

輸出:spa

parent
parent
parent
child
child
grandson
parent
parent
parent
child
child
grandson
parent
parent
parent
child
child
grandson
parent
parent
parent
child
child
grandson
parent
parent
parent
child
child
grandson

這裏的ThreadTest類包含兩個Runnbale,就是其中兩個線程,而這個類自己就是一個資源共享類,裏面的status就是控制順序的狀態。主線程內首先建立執行了第二三個線程,使這兩個線程先進入等待狀態,而後再執行主線程的,待主線程完畢以後喚醒其餘兩條線程,這時候可能會進入不應進入的線程三,因此在wait後面又進行了一次判斷,使它能繼續保持等待狀態讓出執行權,直到狀態符合的狀況下進行執行。線程

注意幾個問題:code

一、必定要讓等待的線程先執行,否則會出現主線程通知時,沒有找到等待的線程而產生的阻塞。blog

二、wait以後的再次判斷很重要,由於在超過兩個線程的狀況下,不肯定是否是通知的該線程。資源

相關文章
相關標籤/搜索