多线程协调实例

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

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

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

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

}

这里的ThreadTest类包含两个Runnbale,就是其中两个线程,而这个类本身就是一个资源共享类,里面的status就是控制顺序的状态。主线程内首先创建执行了第二三个线程,使这两个线程先进入等待状态,然后再执行主线程的,待主线程完毕之后唤醒其他两条线程,这时候可能会进入不该进入的线程三,所以在wait后面又进行了一次判断,使它能继续保持等待状态让出执行权,直到状态符合的情况下进行执行。

注意几个问题:

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

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

猜你喜欢

转载自www.cnblogs.com/huanStephen/p/9253745.html