• 多线程面试题系列2_监视线程的简单实现


    题目:

    创建一个类,需要实现两个方法 { 1: add()往类中添加一个对象, 2: size()返回这个类目前的对象数 }
    创建两个线程,第一个线程循环调用10次add()方法,每次同时打印出此时的size()值;
    第二个线程需要在第一个线程打印到第5个元素时输出“Line 2 检测到5号元素”

    • 解法一:

    采用机制:
    wait(), notify()

    需要注意的点:
    将list定义为volatile以保证可见性。
    wait()会释放锁(这也是它与sleep()的区别), notify()/notifyAll()不会。
    要保证thread2首先运行,否则它不会被thread1 notify醒。

    import java.util.LinkedList;
    import java.util.List;
    class Contact {
        volatile List<Object> list = new LinkedList<Object>();
        void add(Object o) {
            list.add(o);
        }
        int size() {
            return list.size();
        }
    }
    public class Question2 {
        public static void main(String[] args) {
            Contact contact = new Contact();
            Object ob = new Object();
    
            Thread thread1 = new Thread(new Runnable() {
                public void run() {
                    synchronized(ob) {
                        for (int i = 0; i < 10; i++) {
                            contact.add(new Object());
                            System.out.println("thread1 add " + contact.size() + "th element");
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (contact.size() == 5) {
                                ob.notify();
                                try {
                                    ob.wait();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            });
            Thread thread2 = new Thread(new Runnable() {
                public void run() {
                    synchronized(ob) {
                        if (contact.size() != 5) {
                            try {
                                ob.wait();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            System.out.println("thread2 检测到5号元素");
                            ob.notify();
                        }
                    }
                }
            });
            thread2.start(); thread1.start();
        }
    }
    
    • 解法二:

    采用机制:
    CountDownLatch:
    CountDownLatch每调用一次countDown()方法减少1个计数,当计数为0时门闩打开。
    await()方法启用门闩。

    需要注意的点:

    这是较好的方法

    import java.util.LinkedList;
    import java.util.List;
    class Contact {
        volatile List<Object> list = new LinkedList<Object>();
        void add(Object o) {
            list.add(o);
        }
        int size() {
            return list.size();
        }
    }
    public class Question2 {
        public static void main(String[] args) {
            Contact contact = new Contact();
            Object ob = new Object();
    
            Thread thread1 = new Thread(new Runnable() {
                public void run() {
                    synchronized(ob) {
                        for (int i = 0; i < 10; i++) {
                            contact.add(new Object());
                            System.out.println("thread1 add " + contact.size() + "th element");
                            try {
                                Thread.sleep(1000);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            if (contact.size() == 5) {
                                ob.notify();
                                try {
                                    ob.wait();
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            });
            Thread thread2 = new Thread(new Runnable() {
                public void run() {
                    synchronized(ob) {
                        if (contact.size() != 5) {
                            try {
                                ob.wait();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            System.out.println("thread2 检测到5号元素");
                            ob.notify();
                        }
                    }
                }
            });
            thread2.start(); thread1.start();
        }
    }
    
  • 相关阅读:
    机器学习——朴素贝叶斯
    机器学习——决策树
    机器学习——线性回归
    机器学习——KNN
    机器学习——数据预处理
    爬虫——scrapy入门
    爬虫——生产者消费者
    想写篇技术性散文
    (景德镇)麻将规则服务描述
    Visual Studio 2013环境下操作vc6/vc7/vc8等低版本平台项目【编译|生成|调试】
  • 原文地址:https://www.cnblogs.com/fromneptune/p/11758977.html
Copyright © 2020-2023  润新知