题目:
创建一个类,需要实现两个方法 { 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();
}
}