方法一、wait()和notifyAll()
public class TestC1 {
LinkedList<String> list = new LinkedList<>();
final int MAX = 10;
public int getCount(){
return list.size();
}
public synchronized void put(String str){
while (getCount() == MAX){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(str);
System.out.println("生产===" + str);
notifyAll();
}
public synchronized String get(){
while (getCount() == 0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String t = list.getFirst();
list.removeFirst();
System.out.println("消费===" + t);
notifyAll();
return t;
}
public static void main(String[] args) {
TestC1 testC1 = new TestC1();
for (int i = 0; i < 2; i++) {
new Thread(()->{
for (int j = 0; j < 50; j++) {
testC1.put(Thread.currentThread().getName()+"==="+j);
}
}).start();
}
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 10; j++) {
testC1.get();
}
}).start();
}
}
}
方法二、ReentrantLock
public class TestC2 {
volatile LinkedList<String> list = new LinkedList<>();
final int MAX = 10;
Lock lock = new ReentrantLock();
Condition putLock = lock.newCondition();
Condition getLock = lock.newCondition();
public int getCount(){
return list.size();
}
public void put(String str){
lock.lock();
try {
while (getCount() == MAX){
try {
putLock.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(str);
System.out.println(Thread.currentThread().getName()+"生产===" + str);
getLock.signalAll();
}finally {
lock.unlock();
}
}
public String get(){
lock.lock();
try {
while (getCount() == 0){
try {
getLock.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String str = list.getFirst();
list.removeFirst();
System.out.println(Thread.currentThread().getName()+"消费=======" + str);
putLock.signalAll();
return str;
}finally {
lock.unlock();
}
}
public static void main(String[] args) {
TestC2 testC1 = new TestC2();
for (int i = 0; i < 2; i++) {
new Thread(()->{
for (int j = 0; j < 50; j++) {
testC1.put(Thread.currentThread().getName()+"==="+j);
}
}).start();
}
for (int i = 0; i < 10; i++) {
new Thread(()->{
for (int j = 0; j < 10; j++) {
testC1.get();
}
}).start();
}
}
}