zoukankan      html  css  js  c++  java
  • 多线程通信笔试题

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

    子线程循环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();
            }
        }
    }
  • 相关阅读:
    在Android studio中,测试输出数组中最大子数组的和
    我所理解的软件开发模式
    java实现随机输出300题四则运算
    Demo(3月28日)
    关于构建之法中小飞问题的个人看法
    对搭档代码的一些意见
    项目复审
    安卓UI测试(基于android studio环境 espresso框架)
    读构建之法后的一些个人感受
    思考题
  • 原文地址:https://www.cnblogs.com/DarrenChan/p/5743219.html
Copyright © 2011-2022 走看看