Java多种方式实现生产者消费者模式

网友投稿 269 2022-12-01


Java多种方式实现生产者消费者模式

实现需求:两个线程交替打印1,0,打印10轮

java多线程口诀:

高内聚,低耦合

线程操作资源类

判断干活通知

防止虚假唤醒

方式一:使用synchronized和Object的wait和notifyAll方法

wait:使当前线程阻塞

notify,notifyAll唤醒当前线程

/**

* 两个线程交替打印1,0 打印10轮

*

* @author Administrator

* @version 1.0 2020年7月12日

* @see ProdConsumerDemo1

* @since 1.0

*

*/

class ShareData1 {

public int number = 0;

public synchronized void increment() throws Exception {

while (number != 0) {

this.wait();

}

number++;

System.out.println(Thread.currentThread().getName() + " " + number);

this.notifyAll();

}

public synchronized void decrement() throws InterruptedException {

while (number != 1) {

this.wait();

}

number--;

System.out.println(Thread.currentThread().getName() + " " + number);

this.notifyAll();

}

}

public class ProdConsumerDemo1 {

public static void main(String[] args) {

ShareData1 shareData = new ShareData1();

new Thread(() -> {

for (int i = 0; i < 10; i++) {

try {

shareData.increment();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}, "A").start();

new Thread(() -> {

for (int i = 0; i < 10; i++) {

try {

shareData.decrement();

} catch (Exception e) {

// TODO Auto-genehttp://rated catch block

e.printStackTrace();

}

}

}, "B").start();

}

}

输出结果

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

方式二:使用jdk1.8的Lock和Condition

class ShareData2 {

private int number = 0;

private Lock lock = new ReentrantLock();

private Condition condition = lock.newCondition();

public void increment() throws Exception {

lock.lock();

try {

while (number != 0) {

condition.await();

}

number++;

System.out.println(Thread.currentThread().getName() + " " + number);

condition.signalAll();

} finally {

lock.unlock();

}

}

public void decrement() throws InterruptedException {

lock.lock();

try {

while (number != 1) {

condition.await();

}

number--;

System.out.println(Thread.currentThread().getName() + " " + number);

condition.signalAll();

} finally {

// TODO: handle finally clause

lock.unlock();

}

}

}

public class ProdConsumerDemo2 {

public static void main(String[] args) {

ShareData2 shareData = new ShareData2();

new Thread(() -> {

for (int i = 0; i < 10; i++) {

try {

shareData.increment();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}, "A").start();

new Thread(() -> {

for (int i = 0; i < 10; i++) {

try {

shareData.decrement();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}, "B").start();

}

}

输出结果

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

A 1

B 0

主要是熟悉Lock和Condition的使用

Lock和Condition相比于synchronized,能够精确唤醒

需求:三个线程A,B,C顺序打印,A打印5次,B打印10次,C打印15次,10轮

class ShareData3 {

private int number = 1;

private Lock lock = new ReentrantLock();

private Condition c1 = lock.newCondition();

private Condition c2 = lock.newCondition();

private Condition c3 = lock.newCondition();

public void print5() throws Exception {

lock.lock();

try {

while (number != 1) {

c1.await();

}

number = 2;

for (int i = 0; i < 5; i++) {

System.out.println(Thread.currentThread().getName() + " " + i);

}

c2.signalAll();

} finally {

// TODO: handle finally clause

lock.unlock();

}

}

public void print10() throws InterruptedException {

lock.lock();

try {

while (number != 2) {

c2.await();

}

number=3;

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName() + " " + i);

}

c3.signalAll();

} finally {

// TODO: handle finally clause

lock.unlock();

}

}

public void print15() throws InterruptedException {

lock.lock();

try {

while (number != 3) {

c3.await();

}

number = 1;

for (int i = 0; i < 15; i++) {

System.out.println(Thread.currentThread().getName() + " " + i);

}

c1.signalAll();

} finally {

// TODO: handle finally clause

lock.unlock();

}

}

}

public class ProdConsumerDemo3 {

public static void main(String[] args) {

ShareData3 shareData3 = new ShareData3();

new Thread(() -> {

try {

for (int i = 0; i < 10; i++) {

shareData3.print5();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}, "A").start();

new Thread(() -> {

try {

for (int i = 0; i < 10; i++) {

shareData3.print10();

}

} catch (Exception e) {

// TODO Auto-generatedQzwWDXR catch block

e.printStackTrace();

}

}, "B").start();

new Thread(() -> {

try {

for (int i = 0; i < 10; i++) {

shareData3.print15();

}

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}, "C").start();

}

}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot 统一请求返回的实现
下一篇:Web前端和JAVA应该学哪个?哪个就业形势更胜一筹?
相关文章

 发表评论

暂时没有评论,来抢沙发吧~