线程

voliatle关键字

白昼怎懂夜的黑 提交于 2020-03-03 13:59:26
1.volatile关键字使用:   多线程中存在私有堆栈中的值和公共堆栈中的值不同步的问题。什么意思呢?可能线程在一个地方修改了内存中变量的值,而其它地方线程却从私有堆栈中去读取不一致的变量值。关键字volatile 的主要作用是使在多个线程上可见。也就是,强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值。 线程的私有堆栈: 读取公共内存: 强制从私有堆栈中取值的方法为JVM被设置为-server(不设置-server也是从私有堆栈中获取值)。 package chapter2; public class VolatileTest { static class RunThread extends Thread{ private boolean isRunning = true; public boolean isRunning() { return isRunning; } public void setRunning(boolean isRunning) { this.isRunning = isRunning; } @Override public void run() { super.run(); System.out.println("进入run 了"); while (isRunning) { } System.out.println("线程被停止了!

15_volatile

£可爱£侵袭症+ 提交于 2020-03-03 13:48:05
【volatile概念】 volatile关键字的主要作用是是变量在多个线程间可见。 【注意】   在java中,每一个线程都会有一块工作内存区,其中存放着所有线程共享的主内存中的变量的拷贝。当线程执行时,他在自己的工作内存区中操作这些变量。为了存取一个共享的变量,一个线程通常会先获取并去清除它的内存工作区,把这些共享变量从所有线程的共享内存区中正确地装入到他自己所在的工作内存区中,当线程解锁时保证该内存区中变量的值写回到共享内存中。   一个线程可以执行的操作有:使用(use)、赋值(assign)、装载(load)、存储(store)、锁定(lock)、解锁(unlock)。   而主内存可以执行的操作有:读(read)、写(write)、锁定(lock)、解锁(unlock),每个操作都是原子的。   volatile的作用就是强制线程到主内存(共享内存)里去读取变量,而不去线程工作内存区里去读取,从而实现了多个线程间的变量可见。也就是满足线程安全的可见性。 【线程执行流程图】 【volatile可见性的例子】 package com.higgin.part6; public class MyThread extends Thread{ /** * 加与不加volatile * 不加volatile:main线程中将isRunning设置为flase

6.并发编程--volatile

不问归期 提交于 2020-03-03 13:47:05
并发编程--volatile volatile-说明 volatile关键字的作用是变量在多个线程可见; volatile 关键字是非原子性的 要是实现原子性操作,建议使用atomic类的系列对象:支持原子性操作(注意atomic类只保证本身方法的原子性,并不保证多次操作的原子性) 1. volatile : volatile关键字的作用是变量在多个线程可见; 示例: RunThread.java 说明: 在Java中,每个线程都会有一个工作内存区域,其中存放所有线程共享的主内存中的变量的值得拷贝。当线程执行的时候,在自己的工作内存区域中操作这些变量。为了存取一个共享的变量,一个线程通常先获得锁定并清除当前线程的内存工作区域,把这些共享变量从所有线程的共享内存区域中正确的装入到本身所以在的工作内存区域中,当线程解锁是保证该工作内存中的变量的值写会到共享内存区域中。 * 一个线程可以执行的操作有:使用(use),赋值(assgin),装载(load),存储(store),锁定(lock),解锁(unlock); * 主内存中可以执行的操作有:读(read),写(write),锁定(lock),解锁(unlock); 每个操作都是原子性的。 * volatile 的作用就是强制线程到主内存(共享内存)中去读取变量,而不是去线程工作内存区域里去读取,从而实现了多个线程间的变量可见

Thread和Object类中的重要方法详解

為{幸葍}努か 提交于 2020-03-03 12:01:05
Thread和Object类中的重要方法详解 方法概览 wait、notify、notifyAll 作用、用法 :阻塞阶段、唤醒阶段、遇到中断 直到以下四种情况之一发生时,才会被唤醒 另一个线程调用这个对象的notify()方法且刚好被唤醒的是本线程 另一个线程调用这个对象的notifyAll()方法 过了wait(long timeout)规定的超时时间,如果传入0就是永久等待; 线程自身调用了interrupt() 代码演示:展示wait和notify的基本用法 研究代码执行顺序 证明wait释放锁 public class Wait { public static Object object = new Object ( ) ; static class Thread1 extends Thread { @Override public void run ( ) { synchronized ( object ) { System . out . println ( Thread . currentThread ( ) . getName ( ) + "开始执行了" ) ; try { object . wait ( ) ; } catch ( InterruptedException e ) { e . printStackTrace ( ) ; } System .

Thread和Object类中的重要方法之面试问题总结

 ̄綄美尐妖づ 提交于 2020-03-03 11:55:57
面试问题 1.手写生产者消费者设计模式 点这里 2.用程序实现两个线程交替打印0~100的奇偶数 点这里 3.为什么wait()需要在同步代码块内使用,而sleep()不需要 wait()需要在同步代码块内使用主要让通信变得可靠,防止线程死锁,如果不把wait/notify放在同步代码块中的话,很有可能在执行wait之前,线程很有可能已经切换到了另一个执行notify的线程,这样的话有可能另一个线程先把notify都执行完毕了,那wait永远没有被唤醒了,这就 导致了永久等待或者死锁的发生 ,这就需要把两个方法都放到同步代码块中去。 sleep()只关心自己这个线程 ,和其他线程关系并不大,所以并不需要同步。 4.为什么线程通信的方法wait(),notify()和notifyAll()被定义在Object类里?而sleep定义在Thread类里? 因为在java中,wait(),notify()和notifyAll()属于 锁级别 的操作,而锁是属于某个对象的。 5.wait方法是属于Object对象的,那调用Thread.wait会怎么样? Thread也是个对象,这样调用也没有问题,但是Thread是个特殊的对象, 线程退出的时候会自动执行notify ,这样会是我们设计的流程受到干扰,所以我们一般不这么用。 6.如何选择用notify还是notifyAll?

Java学习笔记(9)

谁都会走 提交于 2020-03-03 11:45:20
等待唤醒机制 应用场景主要是多线程需要共同完成一个事情,比如写一个服务插件,线程A需要服务器传过来的数据,而接收服务器的data是线程B的工作,这时候就可以使用线程间通信,data作为资源类,当没有data时,线程A处于wait状态,线程B处于运行状态,当线程B接收到data时,唤醒线程A 线程B示例 @Override public void run ( ) { while ( true ) { synchronized ( data ) { //如果有数据了 if ( data . flag == true ) { try { //线程B等待 thread_B . wait ( ) ; } catch ( InterruptedException e ) { e . printStackTrace ( ) ; } } //服务器获取数据 略 //。。。。。。 //获取到数据修改标志位 data . flag = true ; //唤醒线程A开始处理数据 thread_A . notify ( ) ; } } } 需要注意的是,即使将一个线程唤醒,这个线程也不一定就能立马运行,因为被唤醒的线程还要经历和其他运行的线程抢“锁”的过程,如果能抢到就开始运行,抢不到就从等待变成被锁的状态 另外,线程间通信,操作的应该是同一个对象,同一个资源 常用的函数 wait ( ) notify

Java 核心内容相关面试题【2】

半世苍凉 提交于 2020-03-03 11:41:08
第一,谈谈final, finally, finalize的区别。 final?修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载 finally?再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。 finalize?方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。 第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?

JVM参数详解

半腔热情 提交于 2020-03-03 10:38:38
内存参数 参数 含义 默认值 示例 说明 -Xms 初始堆大小 物理内存的1/64(<1GB) -Xms1g 默认(MinHeapFreeRatio参数可以调整)空余堆内存小于40%时,JVM就会增大堆直到-Xmx的最大限制. -Xmx 最大堆大小 物理内存的1/4(<1GB) -Xmx1g 默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到 -Xms的最小限制 -Xmn 年轻代大小 -Xmn512m 注意 :此处的大小是(eden+ 2 survivor space).与jmap -heap中显示的New gen是不同的。 整个堆大小=年轻代大小 + 年老代大小 + 持久代大小. 增大年轻代后,将会减小年老代大小.此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8 -XX:NewRatio 年轻代与年老代的比值 -XX:NewRatio=1 -XX:NewRatio=4表示年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5 Xms=Xmx并且设置了Xmn的情况下,该参数不需要进行设置。 -XX:SurvivorRatio Eden区与Survivor区的大小比值 默认8:1:1 设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10 -Xss 每个线程的堆栈大小

计算机基础(下)

血红的双手。 提交于 2020-03-03 10:38:01
计算机基础知识想详解 1、cpu详解 cpu的分类与指令集 x86-64(*****) cpu具有向下兼容性 64的cpu既能运行32位的程序也能运行64位的程序 内核态与用户态(*****) 代表cpu的两种工作状态 1、内核态:运行的程序是操作系统,可以操作计算机硬件 2、用户态:运行的程序是应用程序,不能操作计算机硬件 内核态与用户态的转换 应用程序的运行必然涉及到计算机硬件的操作,那就必须有用户态切换到 内核态下才能实现,所以计算机工作时在频繁发生内核态与用户态的转换 多线程与多核芯片 2核4线程: 2核代表有两个cpu,4线程指的是每个cpu都有两个线程=》假4核 4核8线程 4核代表有4个cpu,8线程指的是每个cpu都有两个线程=》假8核 2、存储器 RAM:内存 ROM:“只读内存” 存放计算机厂商写死计算机上的一段核心程序=》BIOS CMOS:存取速度慢,断电数据丢失,耗电量极低 硬盘: 机械硬盘:磁盘 磁道:一圈数据,对应着一串二进制(1bit代表一个二进制位) 8bit比特位=1Bytes字节 1024Bytes=1KB 1024KB=1MB 1024MB=1GB 1024GB=1TB 1024TB=1PB 200G=200*1000*1000B 扇区: 一个扇区通过为512Bytes 站在硬盘的解读,一次性读写数据的最小单为为扇区

Java并发机制的底层实现--volatile

Deadly 提交于 2020-03-03 05:59:40
Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,JAVA中所使用的并发机制依赖于JVM的实现和CPU的指令。 volatile的应用 在线程并发编程中sychronized和volatile都扮演者重要的角色,volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性“。可见性的意思是当一个线程修改一个共享变量时,另一个线程能读到这个修改的值。如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。 1.volatile的定义与实现原理 Java语言规范第三版中对volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被唯一和一致地更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁更加方便。如果一个字段被声明为volatile,Java线程内存模型确保所有线程看到这个变量的值是一致的。 在了解volatile的实现原理之前,我们先来看下与其实现原理相关的CPU术语与说明。 volatile是如何来保证可见性的呢?让我们在X86处理器下通过工具获取JIT编译器生成的汇编指令来查看对volatile进行写操作时