java线程与cpu线程_坑惨了什么意思

java线程与cpu线程_坑惨了什么意思在java中,线程间的通信可以使用wait、notify、notifyAll来进行控制。从名字就可以看出来这3个方法都是跟多线程相关的,但是可能让你感到吃惊的是:这3个方法并不是Thread类或者是Runnable接口的方法,而是Object类的3个本地方法。下图是我总结的Java资料,想要资料的话请点795983544暗号CSDN。其实要理解这一点也并不难,调用一个Object的wait与notify/notifyAll的时候,必须保证调用代码对该Object是同步的,也就是说必须在作用等.

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

在java中,线程间的通信可以使用wait、notify、notifyAll来进行控制。从名字就可以看出来这3个方法都是跟多线程相关的,但是可能让你感到吃惊的是:这3个方法并不是Thread类或者是Runnable接口的方法,而是Object类的3个本地方法。
在这里插入图片描述

下图是我总结的Java资料,想要资料的话请点795983544暗号CSDN。

在这里插入图片描述

其实要理解这一点也并不难,调用一个Object的wait与notify/notifyAll的时候,必须保证调用代码对该Object是同步的,也就是说必须在作用等同于synchronized(obj){…}的内部才能够去调用obj的wait与notify/notifyAll三个方法,否则就会报错:

  java.lang.IllegalMonitorStateException:current thread not owner

也就是说,在调用这3个方法的时候,当前线程必须获得这个对象的锁,那么这3个方法就是和对象锁相关的,所以是属于Object的方法而不是Thread,因为不是每个对象都是Thread。所以我们在理解wait、notify、notifyAll之前,先要了解以下对象锁。

多个线程都持有同一个对象的时候,如果都要进入synchronized(obj){…}的内部,就必须拿到这个对象的锁,synchronized的机制保证了同一时间最多只能有1个线程拿到了对象的锁,如下图:

在这里插入图片描述

下面我们来看一下这3个方法的作用:

  • wait:线程自动释放其占有的对象锁,并等待notify
  • notify:唤醒一个正在wait当前对象锁的线程,并让它拿到对象锁
  • notifyAll:唤醒所有正在wait前对象锁的线程

notify和notifyAll的最主要的区别是:notify只是唤醒一个正在wait当前对象锁的线程,而notifyAll唤醒所有。值得注意的是:notify是本地方法,具体唤醒哪一个线程由虚拟机控制;notifyAll后并不是所有的线程都能马上往下执行,它们只是跳出了wait状态,接下来它们还会是竞争对象锁。

下面通过一个常用生产者、消费者的例子来说明。
消息实体类:

package com.podongfeng;

/** * Title: Message.class<br> * Description: 消息实体<br> * Create DateTime: 2016年04月17日 下午1:27 <br> * * @author podongfeng */
public class Message { 
   
}

生产者:

package com.podongfeng;

import java.util.ArrayList;
import java.util.List;

/** * Title: Producer.class<br> * Description: 消息生产者<br> * Create DateTime: 2016年04月17日 下午1:28 <br> * * @author podongfeng */
public class Producer extends Thread { 
   

    List<Message> msgList = new ArrayList<>();

    @Override public void run() { 
   
        try { 
   
            while (true) { 
   
                Thread.sleep(3000);
                Message msg = new Message();
                synchronized(msgList) { 
   
                    msgList.add(msg);
                    msgList.notify(); //这里只能是notify而不能是notifyAll,否则remove(0)会报java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
                }
            }
        } catch (Exception e) { 
   
            e.printStackTrace();
        }
    }

    public Message waitMsg() { 
   
        synchronized(msgList) { 
   
            if(msgList.size() == 0) { 
   
                try { 
   
                    msgList.wait();
                } catch(InterruptedException e) { 
   
                    e.printStackTrace();
                }
            }
            return msgList.remove(0);
        }
    }
}

消费者:

package com.podongfeng;

/** * Title: Consumer.class<br> * Description: 消息消费者<br> * Create DateTime: 2016年04月17日 下午1:28 <br> * * @author podongfeng */
public class Consumer extends Thread { 
   

    private Producer producer;

    public Consumer(String name, Producer producer) { 
   
        super(name);
        this.producer = producer;
    }

    @Override public void run() { 
   
        while (true) { 
   
            Message msg = producer.waitMsg();
            System.out.println("Consumer " + getName() + " get a msg");
        }
    }

    public static void main(String[] args) { 
   
        Producer p = new Producer();
        p.start();
        new Consumer("Consumer1", p).start();
        new Consumer("Consumer2", p).start();
        new Consumer("Consumer3", p).start();
    }
}

消费者线程调用waitMsg去获取一个消息实体,如果msgList为空,则线程进入wait状态;生产这线程每隔3秒钟生产出体格msg实体并放入msgList列表,完成后,调用notify唤醒一个消费者线程去消费。

最后再次提醒注意:
wait、notify、notifyAll并不是Thread类或者是Runnable接口的方法,而是Object类的3个本地方法。
在调用这3个方法的时候,当前线程必须获得这个对象的锁

最后的惯例:点个小赞,好运不断,来个关注,青春常驻,打个小赏,工资疯涨。。。
在这里插入图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/197342.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 具有指令流水线结构的cpu_流水线结构在CPU中的运用是一种

    具有指令流水线结构的cpu_流水线结构在CPU中的运用是一种为什么小小一个CPU,有那么多周期(Cycle)?程序的性能,是由三个因素相乘来衡量的,“指令数×CPI×时钟周期”。和周期相关的只有一个时钟周期,即CPU主频的倒数。一个CPU的时钟周期可以认为是可以完成一条最简单的计算机指令的时间。那为何构造CPU时,有那么多周期?单指令周期处理器一条CPU指令的执行,由FDE三步组成。这个执行过程,至少需花费一个时钟周期。因为在取指令的时候,我们需要通过时钟周期的信号,来决定计数器的自增。很自然,我们希望能确保让这样一整条指令的执行,在一个时钟周期内完成

    2022年8月14日
    2
  • ext.apply()_函数evaluate的应用

    ext.apply()_函数evaluate的应用转载网址:http://www.cnblogs.com/yin-jingyu/archive/2011/07/30/2122176.htmlapply的用法:    Ext中apply及applyIf方法的应用apply及applyIf方法都是用于实现把一个对象中的属性应用于另外一个对象中,相当于属性拷贝。不同的是apply将会覆盖目标对象中的属性,而apply

    2022年7月28日
    2
  • spring源码分析之事务transaction上篇

    spring源码分析之事务transaction上篇

    2021年8月4日
    52
  • oracle 字符串转数组「建议收藏」

    SELECTdistinctREGEXP_SUBSTR(t.llbm1,‘[^;]+’,1,LEVEL,‘i’)ASSTRFROMuser_nbgzlldt,cpcshtinsswheret.shtinsid=s.shtinsidands.wfid=35connectbylevel<=(regexp_count(t.llbm1,’;’)+1)

    2022年4月14日
    79
  • 跳跃表(skiplist )详解及其C++编程实现

    跳跃表(skiplist )详解及其C++编程实现跳表SkipList跳表SkipList1、背景2、定义2.1、SkipList基本数据结构及其实现3、实现4、使用方法4.1、跳表的创建4.2、跳表插入操作参考跳表SkipList1、背景为什么选择跳表?目前经常使用的平衡数据结构有:B树,红黑树,AVL树,SplayTree,Treep等。跳表是平衡树的一种替代的数据结构,但是和红黑树不相同的是,跳表对于树的平衡的实现是基于一种随机化的算法的,这样也就是说跳表的插入和删除的工作是比较简单的。用跳表吧,跳表是一种随机化的数据结构,目前开源软件

    2022年10月19日
    0
  • Linux常用下载工具推荐「建议收藏」

    Linux常用下载工具推荐「建议收藏」[color="#02368d"]Linux常用下载工具推荐转自:http://doc.zoomquiet.org/data/20060730210451/index.html

    2022年7月1日
    65

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号