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();
            }
        }
    }
  • 相关阅读:
    梯度方向问题
    switchsharp
    R语言学习笔记:sort、rank、order、arrange排序函数
    R语言学习笔记:choose、factorial、combn排列组合函数
    MySQL学习笔记:少用Null
    Oracle学习笔记:11g服务介绍及哪些服务必须开启?
    GreenPlum学习笔记:create or replace function创建函数
    Python学习笔记:出生日期转化为年龄
    Python学习笔记:import sys模块(argv、path、platform、exit)
    Oracle学习笔记:wm_concat函数合并字段
  • 原文地址:https://www.cnblogs.com/DarrenChan/p/5743219.html
Copyright © 2011-2022 走看看