Under my umbrella.

SKII

Less is more.

多线程面试题系列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();
    }
}
posted @ 2019-10-29 15:22  NLYang  阅读(280)  评论(0编辑  收藏  举报