0
点赞
收藏
分享

微信扫一扫

JDK源码——多线程实战

慎壹 2023-03-21 阅读 72


摘要

本博文主要是介绍多线程中的实战问题。通过实际的代码和例子提供大家更多练习和学习以及参考。

模拟多消费者和多生产者的的产生和消费问题

使用的锁的代码

package com.zhuangxiaoyan.jdk.juc.JucLock;

import java.time.LocalDate;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* @Classname ProducerSumer
* @Description
* @Date 2021/11/27 7:59
* @Created by xjl
*/

class ShareData{
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()+"\t"+number);
//通知唤醒
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}

public void decrement()throws Exception{
lock.lock();
try {
//判断
while (number==0){
//等待 不能生产
condition.await();
}
//干活
number--;
System.out.println(Thread.currentThread().getName()+"\t"+number);
//通知唤醒
condition.signalAll();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}



public class ProducerSumer {
public static void main(String[] args) {
ShareData shareData=new ShareData();
new Thread(()->{
for (int i=1;i<=5;i++){
try {
shareData.increment();
} catch (Exception e) {
e.printStackTrace();
}
}
},"AAA").start();

new Thread(()->{
for (int i=1;i<=5;i++){
try {
shareData.decrement();
} catch (Exception e) {
e.printStackTrace();
}
}
},"BBB").start();
}
}

使用原子类和volatile实现

package com.zhuangxiaoyan.jdk.juc.JucLock;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
* @Classname MQDemo
* @Description TODO
* @Date 2021/11/27 8:45
* @Created by xjl
*/

class MyResource {
private volatile Boolean FLAG = true;//默认开启生产和消费

private AtomicInteger atomicInteger = new AtomicInteger();

BlockingQueue<String> blockingQueue = null;

//构造函数
public MyResource(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
System.out.println(blockingQueue.getClass().getName());
}

public void Producer() throws Exception {
String data = null;
boolean retvalue;
while (FLAG) {
data = atomicInteger.incrementAndGet() + "";
retvalue = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);
if (retvalue) {
System.out.println(Thread.currentThread().getName() + "\t插入队列" + data + "成功");
} else {
System.out.println(Thread.currentThread().getName() + "\t插入队列" + data + "失败");
}
TimeUnit.SECONDS.sleep(1);
}
System.out.println(Thread.currentThread().getName() + "\t大老板叫停了,表示FLAG=false,生产动作结束\n");
}

public void Consumer() throws Exception {
String result = null;
while (FLAG) {
result = blockingQueue.poll(2L, TimeUnit.SECONDS);
if (null == result || result.equalsIgnoreCase("")) {
FLAG = false;
System.out.println(Thread.currentThread().getName() + "\t 超时没有消费任务 消费退出");
return;
}
System.out.println(Thread.currentThread().getName() + "\t消费队列" + result + "成功");
}
}

public void stop() {
this.FLAG = false;
}

}

public class MQDemo {
public static void main(String[] args) throws InterruptedException {
MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10));
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t生产线程启动……");
try {
myResource.Producer();
} catch (Exception e) {
e.printStackTrace();
}
}, "生产线程").start();

new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t消费线程启动……");
try {
myResource.Consumer();
} catch (Exception e) {
e.printStackTrace();
}
}, "消费线程").start();

TimeUnit.SECONDS.sleep(5);
System.out.println("停止生产和消费的过程……");
myResource.stop();

}

}

模拟多线程的顺序调用

多线程之间按顺序调用,实现A->B->C三个线程启动,要求如下: AA打E印5次,BB打印10次,CC打E15次。

package com.zhuangxiaoyan.jdk.juc.JucLock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
* @Classname ReentrantLockDemo
* @Description 多线程之间按顺序调用,实现A->B->C三个线程启动,要求如下: AA打E印5次,BB打印10次,CC打E15次
* @Date 2021/11/27 8:21
* @Created by xjl
*/

class ShareResource{
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 printA(){
lock.lock();
try {
//判断
while (number!=1){
c1.await();
}
//干活
for (int i=1;i<=5;i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
//通知
number=2;
c2.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}

public void printB(){
lock.lock();
try {
//判断
while (number!=2){
c2.await();
}
//干活
for (int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
//通知
number=3;
c3.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}

public void printC(){
lock.lock();
try {
//判断
while (number!=3){
c3.await();
}
//干活
for (int i=1;i<=15;i++){
System.out.println(Thread.currentThread().getName()+"\t"+i);
}
//通知
number=1;
c1.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}

}
public class ReentrantLockDemo {

public static void main(String[] args) {
ShareResource shareResource=new ShareResource();

new Thread(()->{
for (int i=1;i<=10;i++){
shareResource.printA();
}
},"AAA").start();
new Thread(()->{
for (int i=1;i<=10;i++){
shareResource.printB();
}
},"BBB").start();
new Thread(()->{
for (int i=1;i<=10;i++){
shareResource.printC();
}
},"CCC").start();
}
}

手写线程池的实现

博文参考

举报

相关推荐

0 条评论