线程中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); } }