多线程通信笔试题

一道关于多线程通信的笔试题,个人觉得值得推荐。
问题描述:

子线程循环10次,主线程循环100次,接着又回到子线程循环10次,接着又回到主线程循环100次。以此类推,总共循环50次。
问题分析:

显然,这是一道多线程的问题。由于开启多个线程之后,是靠CPU分发时间片运行的,谁拿到时间片谁运行。但是可能A线程刚好运行到一半,时间片就给了B线程,这样就会导致数据产生错误。由此,我们用synchronized进行上锁,即便拿到时间片,但由于上锁的对象(即钥匙)别的线程没有释放,所以也只能干等,直到时间片又被对方拿走,这样就避免了数据的错误。本题中,涉及到了两个线程循环执行,显然需要考虑线程间的通信,即wait()和notify()。这两个方法是object类的方法,如果在线程A中调用了obj.wait()方法,那么A就停止等待,等到其他线程调用obj.notify()方法为止。这时,obj显然成了多个线程之间的通信手段。
这里还要强调一点,wait()和notify()不可以轻易调用,他们必须包含在对应的synchronized语句中,他们都需要首先获得目标对象的一个监视器。
问题求解:

package thread;

public class Demo5 {
    public static void main(String[] args) {
        final Business business = new Business();
        new Thread(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < 50; i++) {
                    business.sub(i);
                }
            }
        }).start();

        for (int i = 0; i < 50; i++) {
            business.main(i);
        }
    }

    static class Business {
        // 是否轮到子线程
        boolean isSub = true;

        public synchronized void sub(int i) {
            // 如果没有轮到子线程,进去就阻塞
            if (!isSub) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 0; j < 10; j++) {
                System.out.println("循环次数:" + (i + 1) + ",子线程" + (j + 1));
            }
            isSub = false;
            this.notify();
        }

        public synchronized void main(int i) {
            // 如果没有轮到主线程,进去就阻塞
            if (isSub) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int j = 0; j < 100; j++) {
                System.out.println("循环次数:" + (i + 1) + ",主线程" + (j + 1));
            }
            isSub = true;
            this.notify();
        }
    }
}
原文地址:https://www.cnblogs.com/DarrenChan/p/5743219.html