练习(生产者消费者模式):
自定义同步容器,容器容量上限为10。可以在多线程中应用,并保证数据线程安全。
方式一:使用同步
public class TestContainer01<E> {
private final LinkedList<E> list = new LinkedList<>();
private final int MAX = 10;
private int count = 0;
public synchronized int getCount(){
return count;
}
public synchronized void put(E e){
while(list.size() == MAX){
try {
this.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
list.add(e);
count++;
this.notifyAll();
}
public synchronized E get(){
E e = null;
while(list.size() == 0){
try{
this.wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
e = list.removeFirst();
count--;
this.notifyAll();
return e;
}
public static void main(String[] args) {
final TestContainer01<String> c = new TestContainer01<>();
// 10个生产者
for(int i = 0; i < 10; i++){
new Thread(new Runnable() {
public void run() {
for(int j = 0; j < 5; j++){
System.out.println(c.get());
}
}
}, "consumer"+i).start();
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 2个生产者
for(int i = 0; i < 2; i++){
new Thread(new Runnable() {
public void run() {
for(int j = 0; j < 25; j++){
c.put("container value " + j);
}
}
}, "producer"+i).start();
}
}
}
方式二:使用lock
public class TestContainer02<E> {
private final LinkedList<E> list = new LinkedList<>();
private final int MAX = 10;
private int count = 0;
private Lock lock = new ReentrantLock();
private Condition producer = lock.newCondition();
private Condition consumer = lock.newCondition();
public int getCount(){
return count;
}
public void put(E e){
lock.lock();
try {
while(list.size() == MAX){
System.out.println(Thread.currentThread().getName() + " 等待。。。");
// 进入等待队列。释放锁标记。
// 借助条件,进入的等待队列。
producer.await();
}
System.out.println(Thread.currentThread().getName() + " put 。。。");
list.add(e);
count++;
// 借助条件,唤醒所有的消费者。
consumer.signalAll();
} catch (InterruptedException e1) {
e1.printStackTrace();
} finally {
lock.unlock();
}
}
public E get(){
E e = null;
lock.lock();
try {
while(list.size() == 0){
System.out.println(Thread.currentThread().getName() + " 等待。。。");
// 借助条件,消费者进入等待队列
consumer.await();
}
System.out.println(Thread.currentThread().getName() + " get 。。。");
e = list.removeFirst();
count--;
// 借助条件,唤醒所有的生产者
producer.signalAll();
} catch (InterruptedException e1) {
e1.printStackTrace();
} finally {
lock.unlock();
}
return e;
}
public static void main(String[] args) {
final TestContainer02<String> c = new TestContainer02<>();
// 10个消费者
for(int i = 0; i < 10; i++){
new Thread(new Runnable() {
public void run() {
for(int j = 0; j < 5; j++){
System.out.println(c.get());
}
}
}, "consumer"+i).start();
}
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
// 2个生产者
for(int i = 0; i < 2; i++){
new Thread(new Runnable() {
public void run() {
for(int j = 0; j < 25; j++){
c.put("container value " + j);
}
}
}, "producer"+i).start();
}
}
}
网友评论