问题
使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果add时,队列已经满,则add线程要等待,直到队列有空闲空间。
答案
//这是一段错误的实现代码
package java并发学习.自己实现线程安全的队列;
import java.util.LinkedList;
/**
* Created by h on 17-2-2.
*/
class MyQueue {
int sum = 100;
LinkedList<Integer> lls = new LinkedList<>();
public Integer get() {
if (lls.size() > 0) {
int res = lls.get(0);
lls.remove(0);
return res;
} else return -1;
}
public void put(int i) {
lls.add(lls.size(), i);
}
}
public class Main {
public static void main(String[] args) {
MyQueue q = new MyQueue();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
if (q.lls.size() < 100)
q.put(i);
System.out.println("PUT " + i);
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
if (q.lls.size() > 0)
System.out.println("GET " + q.get());
}
}
});
t1.start();
t2.start();
}
}
解法
package java并发学习.自己实现线程安全的队列;
import java.util.LinkedList;
/**
* Created by h on 17-2-2.
*/
class MyQueue {
int sum = 100;
LinkedList<Integer> lls = new LinkedList<>();
public Integer get() {
synchronized (lls) {
while (lls.size()<=0){
try {
lls.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lls.notify();
}
return lls.remove(0);
}
public void put(int i) {
synchronized (lls){
while (lls.size() >= sum){
try {
lls.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lls.notify();
lls.add(i);
System.out.println("put " + i);
}
}
}
public class Main {
public static void main(String[] args) {
MyQueue q = new MyQueue();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
System.out.println("get " + q.get());
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
q.put(i);
}
}
});
t1.start();
t2.start();
}
}