多线程协调实例

用好多线程重要的是协调线程调用资源,下面看一个实例:

三个线程,第一个线程循环输出三条信息,第二个线程循环输出两条信息,第三个线程循环输出一条信息,按照一二三线程顺序依次输出,然后按照这个顺序循环五回。

 多线程依次输出,依次控制就是多线程需要访问的共享资源。

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();
        }
    }

}

输出:

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后面又进行了一次判断,使它能继续保持等待状态让出执行权,直到状态符合的情况下进行执行。

注意几个问题:

1、一定要让等待的线程先执行,不然会出现主线程通知时,没有找到等待的线程而产生的阻塞。

2、wait之后的再次判断很重要,因为在超过两个线程的情况下,不确定是不是通知的该线程。

posted @ 2018-07-02 14:45  huanStephen  阅读(523)  评论(0编辑  收藏  举报