基础知识巩固五(问题)
一、没有引用变量,那些在堆里new出来的值何时回收
首先引用变量是在栈里的,new 出来的对象是在堆里的,二者的联系也就是堆里的对象的地址赋给了引用变量,引用变量存储的也就是这个对象的引用
那么如果没有引用变量,也就是new Circle()这种,没有引用变量,它首先会在堆里创建一个属于它的内存空间,然后如果是new Circle().method()这样
可以使用对象的方法,否则,当系统内存不足或者程序运行完后,堆里面的这块内存都会被虚拟机自动收回。
存储区域 | 存储内容 | 优点 | 缺点 | 回收 |
---|---|---|---|---|
栈 | 基本类型的变量和对象的引用变量 | 存取速度比堆要快,仅次于寄存器,栈数据可以共享 | 存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量 | 当超过变量的作用域后,Java会自动释放掉该变量,内存空间可以立即被另作他用 |
堆 | 由new等指令创建的对象和数组 | 可以动态地分配内存大小,生存期也不必事先告诉编译器 | 由于要在运行时动态分配内存,存取速度较慢 | 由Java虚拟机的自动垃圾回收器来回收不再使用的数据 |
参考链接:
http://blog.csdn.net/bangbt/article/details/6232299
http://blog.csdn.net/weixin_35813749/article/details/52374749
二、关于wait/notify与await/signal的
wait/notify都是在java.lang.object包下
wait() 与 notify/notifyAll 方法必须在同步代码块(synchronized)中使用
notify 通知的顺序不能错
假设在线程A中执行wait(),在线程B中执行notify()。但如果线程B先执行了notify()然后结束了,线程A才去执行wait(),那此时,线程A将无法
被正常唤醒了(还可以通过interrupt()方法以抛出异常的方式唤醒)。
await/signal都是java.util.concurrent.locks包的接口Condition的方法,Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,也就是说,await/signal比wait/notify更加的灵活。
synchronized 块或方法对于一个对象只有一个condition queue,这样如果在这个queue上如果有多个condition predicate, 比如isFull(),isEmpty() ,
就必须用notfiyAll()方法, 会有context switch及获取锁的性能损失。
Lock 接口的实现允许锁在不同的作用范围内获取和释放,并允许以任何顺序获取和释放多个锁
参考链接:
https://www.cnblogs.com/jalja/p/5895051.html
https://www.cnblogs.com/alphablox/archive/2013/01/20/2868479.html
代码部分: 1 public class Test {
2 public static Buffer buffer = new Buffer(); 3 static StringBuffer sb = new StringBuffer(); 4 5 static class Producer implements Runnable{ 6 int i = 1; 7 @Override 8 public void run() { 9 try{ 10 while (true){ 11 buffer.write(i++); //sb.append("生产者生产产品:" + i).append("\n"); //今天在把输出控制台的语句放在了这里出现了问题,下边解释12 Thread.sleep((int)(Math.random()*100)); 13 if (i >= 70) 14 break; 15 } 16 System.out.println(sb.toString()); 17 }catch (InterruptedException e){ 18 e.printStackTrace(); 19 } 20 21 } 22 } 23 24 static class Consumer implements Runnable{ 25 @Override 26 public void run() { 27 try { 28 while (true) { 29 buffer.read(); 30 Thread.sleep((int) (Math.random() * 100)); 31 } 32 } catch (InterruptedException e) { 33 e.printStackTrace(); 34 } 35 } 36 } 37 38 39 static class Buffer{ 40 public static Lock lock = new ReentrantLock(); 41 public static Condition isFull = lock.newCondition(); 42 public static Condition isEmpty = lock.newCondition(); 43 Queue<Integer> queue = new PriorityQueue<>(); 44 public void write(int i) { 45 lock.lock(); 46 try { 47 while(!queue.isEmpty()){ 48 isFull.await(); 49 } 50 queue.offer(i); 51 sb.append("生产者生产产品:" + i).append("\n");//important 52 isEmpty.signal(); 53 } catch (InterruptedException e) { 54 e.printStackTrace(); 55 }finally { 56 lock.unlock(); 57 } 58 } 59 60 public int read(){ 61 int result = 0; 62 lock.lock(); 63 try { 64 while(queue.isEmpty()){ 65 isEmpty.await(); 66 } 67 result = queue.remove(); 68 sb.append("消费者购买商品:" + result).append("\n\n");//important 69 isFull.signal(); 70 } catch (InterruptedException e) { 71 e.printStackTrace(); 72 }finally { 73 lock.unlock(); 74 return result; 75 } 76 } 77 } 78 public static void main(String[] args){ 79 ExecutorService executor = 80 Executors.newFixedThreadPool(2); 81 executor.execute(new Producer()); 82 executor.execute(new Consumer()); 83 executor.shutdown(); 84 } 85 86 }
总结:
使用condition对象必须先获取到锁,也就是必须要lock.lock().其次你想通过控制台输出语句的时候要注意,condition.signal()方法会唤醒原来阻塞的线程,然后来争夺资源,
这样控制台的输出语句可能就没法正常输出,也就是生产者会一次性生产两个,就是因为提前唤醒抢夺资源这个点(PS:连i++这个过程都没法正常进行,因为这个表达式不是原子的),所以针对不是原子的操作,要多注意线程唤醒语句:condition.signal().
三、关于LinkedList与Stack
LinkedList是通过双向链表实现的,他实现了Dueue双向队列接口
Stack是Vector的子类,是线程安全的,相当于数据结构里堆栈的结构,先进后出
额外补充:
ArrayList、Vector、Stack都是通过数组实现的
四、信号量(Semaphore)的运用
在java中,使用了synchronized关键字和Lock锁实现了资源的并发访问控制,在同一时间只允许唯一了线程进入临界区访问资源(读锁除外),这样子控制的主要目的是为了解决多个线程并发同一资源造成的数据不一致的问题。在另外一种场景下,一个资源有多个副本可供同时使用,比如打印机房有多个打印机、厕所有多个坑可供同时使用,这种情况下,Java提供了另外的并发访问控制--资源的多副本的并发访问控制,今天学习的信号量Semaphore即是其中的一种。
参考链接:
http://blog.csdn.net/zbc1090549839/article/details/53389602
https://www.cnblogs.com/XHJT/p/3910406.html
测试代码:
1 public class Test { 2 private static Semaphore semaphore = new Semaphore(2); 3 4 public static void main(String[] args){ 5 for (int i = 0;i<10;i++){ 6 new Thread(new Runnable() { 7 8 @Override 9 public void run() { 10 while(true) { 11 try { 12 semaphore.acquire(1); 13 System.out.println(Thread.currentThread().getName()); 14 Thread.sleep(1000); 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 }finally { 18 semaphore.release(1); 19 } 20 } 21 } 22 },"线程:"+i).start(); 23 } 24 25 } 26 27 }
转载于:https://www.cnblogs.com/shigeng/p/8551855.html
基础知识巩固五(问题)相关推荐
- 农村信用社计算机基础知识,农村信用社计算机基础知识题五
信用社 农村信用社计算机基础知识题五第五套模拟题 (1)由两个栈共享一个存储空间的好处是 A)减少存取时间,降低下溢发生的机率 B)节省存储空间,降低上溢发生的机率 C)减少存取时间,降低上溢发生的机 ...
- Mysql数据库基础知识(五)之:视图、变量、存储过程、函数、流程控制结构
第一部分:Mysql数据库基础知识(一)之 基础查询----分组查询 第二部分:Mysql数据库基础知识(二)之 连接查询----子查询-----分页查询------union联合查询 第三部分:My ...
- IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列
1.引言 消息是互联网信息的一种表现形式,是人利用计算机进行信息传递的有效载体,比如即时通讯网坛友最熟悉的即时通讯消息就是其具体的表现形式之一. 消息从发送者到接收者的典型传递方式有两种: 1)一种我 ...
- 达梦数据库基础知识(五)安全用户管理之“三权分立”
为了保证数据库系统的安全性,DM数据库采用"三权分立"或"四权分立"的安全机制,"三权分立"时系统内置三种系统管理员,包括数据库管理员.数据 ...
- 工业控制计算机硬件基础知识,第五章 工业控制计算机及其接口技术知识 机电一体化课件.ppt...
第五章 工业控制计算机及其接口技术知识 机电一体化课件.ppt (3) 编程方法举例 1. A/D编程 下面C语言例程为软件触发A/D和软件查询方式完成A/D转换功能,模拟输入范围为±5V增益为1. ...
- 模拟电路技术之基础知识(五)
频率响应 文章目录 第五章 放大电路的频率响应 频率响应概述 研究放大电路频率响应的必要性 频率响应的基本概念 一.高通电路 一.低通电路 晶体管的高频等效模型 1.晶体管的混合$\pi$模型 2.高 ...
- 用《叩响C#之门》复习C#基础知识 第五章 枚举、结构体和数组
1.枚举类型(Enumeration type) enum 类型名{枚举项 逗号隔开} 是一种数据类型不是变量,如: enum WeekDays {Sunday,Monday,Tuesday,We ...
- 基础知识(五)对齐变换相关函数
在机器学习.图像处理中,经常要计算两个特征向量之间形状的距离,比如我用face++检测到两张人脸的特征点数据,我们要用人脸的特征点计算出这两张人脸的之间的相似度,这个时候我们就需要对这两张人脸进行对齐 ...
- 软件测试的基础知识(五)
本篇文章,从第五个角度来谈软件测试的方法,按是否运行程序划分,可以分为: 静态测试 动态测试 1.静态测试 静态测试,指不运行被测程序本身,仅通过分析或者检查源程序的语法.结构.过程.接口等来检查程序 ...
- C++基础知识(五)C++的一些特性
有人说,C++是由C语言往前走了一步而变成的,因为从语法角度上来看,C++就是在C的基础上自增了一.那么,C++和C语言相比,除了类(就是面向对象的那一套东西之外),基础语法增加的有哪些呢. 1.强制 ...
最新文章
- Golang实现requests库
- python大神-6年Python大神总结10个开发技巧,80%的人都不会
- 【IM】关于监督降维的理解
- [TJOI2010]阅读理解
- python连接不上数据库_pycharm连接mysql数据库连接不上
- vi @-function
- 分布式系统认证方案_分布式系统认证需求_Spring Security OAuth2.0认证授权---springcloud工作笔记135
- php判断直线相交,zoj 1158 判断2线段完全相交
- flex中list或Combox中的子项上移下移操作
- 《深入理解JavaScript闭包和原型》笔记
- CS61A自学者学习指南
- 正则表达式 匹配一个数字
- 大数据自学全套教程,免费分享,赶紧码起来!(纯干货系列)
- FPGA作为电力电子设备控制器的实践
- MyExcel 2.2.0 版本发布,支持公式导出
- 苹果apple账号授权登录第三方APP
- 【万里征程——Windows App开发】SemanticZoom视图切换
- Race condition between wait_event and wake_up
- 李开复写给中国学生家长的信
- linux安装git
热门文章
- 拓端tecdat|Python、R对小说进行文本挖掘和层次聚类可视化分析案例
- 基于钉钉小程序做一个记事本
- 一个react项目案例02 注册和登陆实现原理分析
- model.load_state_dict(checkpoint[‘state_dict‘]) KeyError: ‘state_dict‘
- version `GLIBCXX_3.4.22‘ not found
- GRAPH ATTENTION NETWORKS 学习翻译
- 目标检测|YOLOv2原理与实现(附YOLOv3)
- python读取mat文件报错【NotImplementedError: Please use HDF reader for matlab v7.3 files】
- 【Python】 html解析BeautifulSoup
- python 关于main函数以及if __name__=='__main__'的理解