线程中wait()和notify()整合synchronized简单使用
pom文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | <?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> |
代码部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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(); } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | 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(); } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 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; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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 ); } } |
引入多个线程处理数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | 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 ; } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 ); } } |
标签:
多线程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异