JDK:1.8
背景:
当我测试多生产和多消费 操作值-假死时,分别两个生产和消费线程,每个线程内循环两次相应方法
问题:
打印日志 发现,消费2有一次 wait 在未唤醒时就接着往下执行了,不知道这是为什么?
先把测试代码附上
日志中始终有
消费者2 WAITING 0 解除 value=null
消费者2 WAITING 1
正常解除 value后面是有值的,这次却没有,虽然没影响功能,但感到很奇怪。
/**
* 3.1.11.2 多生产和多消费 操作值-假死
* Created by ironlee on 17/12/23.
*/
public class ProducerAndConsumerAllWait {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
/**
* 生产
* @param lock
*/
public void producer(Object lock){
synchronized (lock){
try {
int i = 0 ;
while(StringUtils.isNotBlank(getValue())) {
System.out.println(Thread.currentThread().getName()+" WAITING value="+getValue()+" "+(i++));
lock.wait();
}
String value = System.currentTimeMillis()+"-"+System.nanoTime();
System.out.println(Thread.currentThread().getName()+" RUNNABLE value="+value);
setValue(value);
lock.notify();
// System.out.println(System.currentTimeMillis()+"-"+System.nanoTime()+" 生产者 "+Thread.currentThread().getName()+" NOTIFY value="+getValue());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 消费
* @param lock
*/
public void consumer(Object lock){
synchronized (lock){
try{
int i = 0 ;
// 为什么 没唤醒 wait能接着往下走?
while(StringUtils.isBlank(getValue())){
System.out.println(Thread.currentThread().getName()+" WAITING "+(i));
lock.wait();
System.out.println(Thread.currentThread().getName()+" WAITING "+(i) + " 解除 value="+getValue());
i++;
}
System.out.println(Thread.currentThread().getName()+" RUNNABLE value="+getValue());
setValue(null);
lock.notify();
// System.out.println(System.currentTimeMillis()+"-"+System.nanoTime()+" 消费者 "+Thread.currentThread().getName()+" NOTIFY value="+getValue());
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final Object lock = new Object();
final ProducerAndConsumerAllWait domain = new ProducerAndConsumerAllWait();
final int count = 2;
Runnable producer = new Runnable() {
@Override
public void run() {
synchronized (lock){
int i = 0 ;
while( i < count ){
System.out.println( Thread.currentThread().getName()+" 序号="+i);
domain.producer( lock );
i++;
}
}
}
};
Runnable consumer = new Runnable() {
@Override
public void run() {
synchronized (lock){
int i = 0 ;
while(i< count){
System.out.println( Thread.currentThread().getName()+" 序号="+i);
domain.consumer( lock );
i++;
}
}
}
};
for( int ii = 0 ; ii < 2 ; ii++){
Thread producerT = new Thread(producer);
producerT.setName("生产者"+(ii+1));
producerT.start();
Thread consumerT = new Thread(consumer);
consumerT.setName("消费者"+(ii+1));
consumerT.start();
}
try {
Thread.sleep( 1000L );
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread[] threadArray = new Thread[Thread.currentThread().getThreadGroup().activeCount()];
Thread.currentThread().getThreadGroup().enumerate( threadArray );
for( Thread t : threadArray ){
System.out.println( t.getName() + " " + t.getState() );
}
}
}
分享到:
相关推荐
Java多线程编程是Java开发中的...以上内容只是《Java多线程编程核心技术》教程中的一部分核心知识点,实际学习中还需要结合具体示例和实践来深入理解和掌握。通过学习,开发者可以编写出高效、稳定的多线程Java程序。
4. 并发处理:在多线程环境中,需正确管理和同步HttpClient实例。 总的来说,Apache Commons HttpClient 3.1是Java开发中处理HTTP通信的强大工具,虽然现在已经有了更新的版本,但3.1版本在许多项目中仍被广泛使用...
《Apache Commons Lang 3.1:Java编程的强大工具》 Apache Commons Lang 是一个Apache软件基金会提供的Java类库,专门用于处理日常编程任务。这个库包含了大量实用的工具类,极大地扩展了Java的标准库,其中的版本...
本资料"Java多线程编程核心技术.zip"深入探讨了这些核心技术,并提供了源码供学习者实践和理解。 1. **线程的创建与启动** - 继承Thread类:自定义类继承Thread类,重写run()方法,然后创建该类对象并调用start()...
《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...
这里提到的三个JAR文件——`commons-beanutils.jar`、`commons-collections-3.1.jar`和`commons-pool-1.2.jar`,都是Apache Commons项目的一部分,分别涉及Bean操作、集合操作和对象池化。 **1. `commons-beanutils...
Java多线程编程实战指南...本书以基本概念、原理与方法为主线,辅以丰富的实战案例和生活化实例,并从Java虚拟机、操作系统和硬件多个层次与角度出发,循序渐进、系统地介绍Java平台下的多线程编程核心技术及相关工具。
backport-util-concurrent-3.1.jar是一个Java库,它提供了一些并发工具类,用于简化多线程编程。这个库包含了许多实用的工具类,如`FutureTask`、`CountDownLatch`、`Semaphore`等,这些工具类可以帮助开发者更好地...
7. **性能优化**:为了提高性能,开发者可以调整ActiveMQ的相关配置,如设置消息持久化策略、优化网络连接、启用多线程处理等。此外,监控和日志记录也是确保系统稳定运行的关键,activemq-ra-3.1-M6.jar提供了丰富...
Apache Commons Lang 3.6 是一个Java库,它提供了对Java语言核心类的扩展,以增强功能和提高开发效率。这个库是针对Java 7.0及更高版本设计的,包含了许多实用工具类,用于处理字符串、数组、日期、枚举、数值、反射...
在实现HOOK的过程中,开发者需要熟悉Windows API,尤其是关于进程和线程管理的部分,以及理解和运用函数指针、钩子回调函数等概念。 压缩包中的CWechatHelper可能是实现HOOK功能的核心代码库,它可能包含以下部分:...
标题提及的"jsp-api.jar(2.3)与servlet-api.jar (3.1)"指的是两个关键的Java Web开发库,它们是JavaServer Pages(JSP)和Servlet技术的API实现。JSP 2.3是用于创建动态网页的Java平台标准,而Servlet 3.1则是...
### Java多线程核心编程技术 #### 一、Java多线程基础 ##### 1.1 线程的概念 在计算机科学中,线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。在Java中,通过创建`...
libgo-3.1-stable是一个针对Go语言(Golang)开发的库,其核心在于提供高效的并发处理能力,尤其在分布式和云原生环境中发挥着重要作用。此版本的libgo稳定且强大,它通过引入协程(Goroutine)的概念,极大地优化了...
在当今高度并发的应用环境中,Java多线程技术被广泛应用于处理数据库操作,以提升系统的响应速度和处理能力。本文将基于一个具体的Java多线程操作数据库的应用程序,深入探讨其背后的原理、实现细节以及潜在的挑战。...
Apache Commons Lang 是一个Java工具包,专门设计来增强和扩展Java的标准库。在这个"commons-lang-3-3.1"版本中,我们找到了一个jar包和源码包,这些都是开发者们进行程序开发的重要资源。这个版本是Lang项目的第3版...
`SingleClientConnManager`和`MultiThreadedHttpConnectionManager`分别是单线程和多线程环境下的实现。 二、请求构建与执行 1. 请求参数:`NameValuePair`类用于表示键值对,可以用来构造POST请求的数据。`...
标题《Java多线程编程深入详解》所涉及的知识点涵盖了Java多线程编程的核心思想、原理以及在实际开发中可能遇到的问题和解决方案。以下是对这些知识点的详细阐述: 1. 多进程与多线程概念的区分和理解 - 进程是...
重命名 实验三多:线程同步与协作:生产者与消费者 为 实验三:多线程同步与协作:生产者与消费者 实验九:使用jdbc存取大文本 add 实验九:使用jdbc存取大文本. 实验二:多线程打字游戏 add 实验二:多线程...