线程中wait()和notify()整合synchronized简单使用
pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.java</groupId>
<artifactId>test-study</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!--tomcat容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<!--引入junit单元测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--判断空的用法 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>study</finalName>
</build>
</project>
代码部分
package com.java.test.synchorized.wait.notify;
import org.apache.commons.lang.StringUtils;
import java.util.Random;
/**
* @Description:
* @Author: Yourheart
* @Create: 2022/10/21 17:20
*/
public class ConsumerThread extends Thread {
private final MyQueue myQueue;
private final Random random = new Random();
public ConsumerThread(MyQueue myQueue) {
this.myQueue = myQueue;
}
@Override
public void run() {
while (true) {
String result = myQueue.get();
if (StringUtils.isNotBlank(result)){
System.out.println("\t\t消费的数据:" + result);
}
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.java.test.synchorized.wait.notify;
import java.util.Random;
/**
* @Description:
* @Author: Yourheart
* @Create: 2022/10/21 17:17
*/
public class ProducerThread extends Thread {
private final MyQueue myQueue;
private final Random random = new Random();
private int index = 0;
public ProducerThread(MyQueue myQueue) {
this.myQueue = myQueue;
}
@Override
public void run() {
while (true) {
String tmp = "生产数据: " + index;
myQueue.put(tmp);
System.out.println(tmp);
index++;
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package com.java.test.synchorized.wait.notify;
/**
* @Description:
* @Author: Yourheart
* @Create: 2022/10/21 17:15
*/
public class MyQueue {
private Object lock=new Object();
private String[] data = new String[10];
/**
* 下一条要获取元素的下标
*/
private int getIndex = 0;
/**
* 下一条要获取元素的下标
*/
private int putIndex = 0;
/**
* data中元素的个数
*/
private int size = 0;
/**
* 向数组中放置元素
* @param element
*/
public synchronized void put(String element) {
if (size == data.length) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
data[putIndex] = element;
notify();
++size;
++putIndex;
if (putIndex == data.length) {
putIndex = 0;
}
}
/**
* 从数组中获取元素
* @return
*/
public synchronized String get() {
if (size == 0) {
try {
/**
* 阻塞线程
*/
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
String result = data[getIndex];
++getIndex;
if (getIndex == data.length) {
getIndex = 0;
}
--size;
/**
* 通知生产者生产数据,因为对象锁是当前的对象,即this对象
*/
notify();
return result;
}
}
package com.java.test.synchorized.wait.notify;
import org.junit.Test;
/**
* @Description:
* @Author: Yourheart
* @Create: 2022/10/21 17:15
*/
public class Main {
@Test
public void test() throws InterruptedException {
MyQueue myQueue = new MyQueue();
ProducerThread producerThread = new ProducerThread(myQueue);
ConsumerThread consumerThread = new ConsumerThread(myQueue);
producerThread.start();
consumerThread.start();
Thread.sleep(10000);
/**
* 进程结束
*/
System.exit(0);
}
}
引入多个线程处理数据
package com.java.test.synchorized.wait.notify;
/**
* @Description 在MyQueue的基础上做升级
* @Author qiuxie
* @Date 2022/10/25 20:25
*/
public class UpgradeMyQueue extends MyQueue{
private Object lock=new Object();
private String[] data = new String[10];
/**
* 下一条要获取元素的下标
*/
private int getIndex = 0;
/**
* 下一条要获取元素的下标
*/
private int putIndex = 0;
/**
* data中元素的个数
*/
private int size = 0;
/**
* 向数组中放置元素
*
* @param element
*/
@Override
public synchronized void put(String element) {
if (size==data.length){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
/**
* 利用迭代,进行第二次抢对象锁
*/
put(element);
}else {
putZero(element);
}
}
/**
* 从数组中获取元素
*
* @return
*/
@Override
public synchronized String get() {
if (size == 0) {
try {
/**
* 阻塞线程
*/
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return get();
}else {
return getZero();
}
}
private String getZero(){
String datum = data[getIndex];
++getIndex;
if (getIndex==data.length){
getIndex=0;
}
/**
* 唤醒生产者生产,因为对象锁是当前对象,this
*/
notify();
return datum;
}
private void putZero(String element){
data[putIndex]=element;
//唤醒等待的消费者线程
notify();
++size;
++putIndex;
if (putIndex==data.length){
putIndex=0;
}
}
}
package com.java.test.synchorized.wait.notify;
import org.springframework.util.StopWatch;
/**
* @Description
* @Author qiuxie
* @Date 2022/10/25 20:40
*/
public class UpgradeMain {
public static void main(String[] args) throws InterruptedException {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
UpgradeMyQueue upgradeMyQueue=new UpgradeMyQueue();
for (int i = 0; i <5 ; i++) {
new ConsumerThread(upgradeMyQueue).start();
new ProducerThread(upgradeMyQueue).start();
}
Thread.sleep(10000);
stopWatch.stop();
System.out.println(stopWatch.getLastTaskTimeMillis()+"毫秒");
System.exit(0);
}
}
浙公网安备 33010602011771号