`
ironlee
  • 浏览: 1223 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

疑问:多生产和多消费 操作值-假死 来自:《JAVA多线程编程核心技术》3.1.11.2

阅读更多
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开发中的...以上内容只是《Java多线程编程核心技术》教程中的一部分核心知识点,实际学习中还需要结合具体示例和实践来深入理解和掌握。通过学习,开发者可以编写出高效、稳定的多线程Java程序。

    commons-httpclient-3.1jar包

    4. 并发处理:在多线程环境中,需正确管理和同步HttpClient实例。 总的来说,Apache Commons HttpClient 3.1是Java开发中处理HTTP通信的强大工具,虽然现在已经有了更新的版本,但3.1版本在许多项目中仍被广泛使用...

    commons-lang3-3.1.jar_2021.07.zip

    《Apache Commons Lang 3.1:Java编程的强大工具》 Apache Commons Lang 是一个Apache软件基金会提供的Java类库,专门用于处理日常编程任务。这个库包含了大量实用的工具类,极大地扩展了Java的标准库,其中的版本...

    Java多线程编程核心技术.zip

    本资料"Java多线程编程核心技术.zip"深入探讨了这些核心技术,并提供了源码供学习者实践和理解。 1. **线程的创建与启动** - 继承Thread类:自定义类继承Thread类,重写run()方法,然后创建该类对象并调用start()...

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...

    commons-beanutils.jar commons-collections-3.1.jar commons-pool-1.2.jar

    这里提到的三个JAR文件——`commons-beanutils.jar`、`commons-collections-3.1.jar`和`commons-pool-1.2.jar`,都是Apache Commons项目的一部分,分别涉及Bean操作、集合操作和对象池化。 **1. `commons-beanutils...

    Java多线程编程实战指南(核心篇)

    Java多线程编程实战指南...本书以基本概念、原理与方法为主线,辅以丰富的实战案例和生活化实例,并从Java虚拟机、操作系统和硬件多个层次与角度出发,循序渐进、系统地介绍Java平台下的多线程编程核心技术及相关工具。

    backport-util-concurrent-3.1.jar

    backport-util-concurrent-3.1.jar是一个Java库,它提供了一些并发工具类,用于简化多线程编程。这个库包含了许多实用的工具类,如`FutureTask`、`CountDownLatch`、`Semaphore`等,这些工具类可以帮助开发者更好地...

    activemq-ra-3.1-M6.jar.zip

    7. **性能优化**:为了提高性能,开发者可以调整ActiveMQ的相关配置,如设置消息持久化策略、优化网络连接、启用多线程处理等。此外,监控和日志记录也是确保系统稳定运行的关键,activemq-ra-3.1-M6.jar提供了丰富...

    commons-lang3-3.1.jar

    Apache Commons Lang 3.6 是一个Java库,它提供了对Java语言核心类的扩展,以增强功能和提高开发效率。这个库是针对Java 7.0及更高版本设计的,包含了许多实用工具类,用于处理字符串、数组、日期、枚举、数值、反射...

    微信3.1.0.41逆向-微信3.1.0.41HOOK接口-vc++实例源码

    在实现HOOK的过程中,开发者需要熟悉Windows API,尤其是关于进程和线程管理的部分,以及理解和运用函数指针、钩子回调函数等概念。 压缩包中的CWechatHelper可能是实现HOOK功能的核心代码库,它可能包含以下部分:...

    jsp-api.jar(2.3)与servlet-api.jar (3.1)

    标题提及的"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多线程核心编程技术 #### 一、Java多线程基础 ##### 1.1 线程的概念 在计算机科学中,线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。在Java中,通过创建`...

    libgo-3.1-stable.tar.gz

    libgo-3.1-stable是一个针对Go语言(Golang)开发的库,其核心在于提供高效的并发处理能力,尤其在分布式和云原生环境中发挥着重要作用。此版本的libgo稳定且强大,它通过引入协程(Goroutine)的概念,极大地优化了...

    java 多线程操作数据库

    在当今高度并发的应用环境中,Java多线程技术被广泛应用于处理数据库操作,以提升系统的响应速度和处理能力。本文将基于一个具体的Java多线程操作数据库的应用程序,深入探讨其背后的原理、实现细节以及潜在的挑战。...

    commons-lang-3-3.1 jar包和源码包

    Apache Commons Lang 是一个Java工具包,专门设计来增强和扩展Java的标准库。在这个"commons-lang-3-3.1"版本中,我们找到了一个jar包和源码包,这些都是开发者们进行程序开发的重要资源。这个版本是Lang项目的第3版...

    commons-httpclient-3.1 java API详细index格式文档

    `SingleClientConnManager`和`MultiThreadedHttpConnectionManager`分别是单线程和多线程环境下的实现。 二、请求构建与执行 1. 请求参数:`NameValuePair`类用于表示键值对,可以用来构造POST请求的数据。`...

    Java多线程编程深入详解

    标题《Java多线程编程深入详解》所涉及的知识点涵盖了Java多线程编程的核心思想、原理以及在实际开发中可能遇到的问题和解决方案。以下是对这些知识点的详细阐述: 1. 多进程与多线程概念的区分和理解 - 进程是...

    java实验实验报告 add 实验一:多线程/2.Runnable接口. 实验八:JDBC数据库编程二-存储过程

    重命名 实验三多:线程同步与协作:生产者与消费者 为 实验三:多线程同步与协作:生产者与消费者 实验九:使用jdbc存取大文本 add 实验九:使用jdbc存取大文本. 实验二:多线程打字游戏 add 实验二:多线程...

Global site tag (gtag.js) - Google Analytics