先看这个
前面提到:
synchronized的锁对象和同步监视器是同一个,因此不能做到A-B-C-D-A-B-C-D
因此对于生产者A、C,消费者B、D;当仓库数量为0时,A生产完,B和D会抢着消费
1、传统的synchronized
代码输出结果:(部分)
A===>1
B===>0
C===>1
B===>0
A===>1
D===>0
public class Test {
public static void main(String[] args) {
Data data=new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"D").start();
}
}
class Data{ //数字资源类
private int number=0;
public synchronized void increment(){
while(number!=0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number++;
System.out.println(Thread.currentThread().getName()+"===>"+number);
this.notifyAll();
}
public synchronized void decrement(){
if(number==0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number--;
System.out.println(Thread.currentThread().getName()+"===>"+number);
this.notifyAll();
}
}
2、lock锁
代码输出结果跟第一个一样,没什么区别,需要通过condition优化
public class Test {
public static void main(String[] args) {
Data data=new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.increment();
}
},"C").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.decrement();
}
},"D").start();
}
}
class Data{ //数字资源类
private int number=0;
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
public void increment(){
lock.lock();
try {
while(number!=0){
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number++;
System.out.println(Thread.currentThread().getName()+"===>"+number);
condition.signalAll();
}finally {
lock.unlock();
}
}
public void decrement(){
lock.lock();
try{
while(number==0){
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number--;
System.out.println(Thread.currentThread().getName()+"===>"+number);
condition.signalAll();
}finally {
lock.unlock();
}
}
}
3、lock锁优化
实现A-B-C-D-A-B-C-D-A-B-C-D
代码结果:
A=======>AAAAAA
B=======>BBBBBB
C=======>CCCCCC
A=======>AAAAAA
B=======>BBBBBB
C=======>CCCCCC
public class Test {
public static void main(String[] args) {
Data data=new Data();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.printA();
}
},"A").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.printB();
}
},"B").start();
new Thread(()->{
for (int i = 0; i < 10; i++) {
data.printC();
}
},"C").start();
}
}
class Data{
int number=1;
Lock lock=new ReentrantLock();
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();
void printA(){
lock.lock();
try{
while(number!=1){
try {
condition1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"=======>AAAAAA");
number=2;
condition2.signal(); //唤醒condition2
}finally {
lock.unlock();
}
}
void printB(){
lock.lock();
try{
while(number!=2){
try {
condition2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"=======>BBBBBB");
number=3;
condition3.signal();
}finally {
lock.unlock();
}
}
void printC(){
lock.lock();
try{
while(number!=3){
try {
condition3.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"=======>CCCCCC");
number=1;
condition1.signal();
}finally {
lock.unlock();
}
}
}