线程

07:线程安全-可见性问题

心不动则不痛 提交于 2020-03-30 22:57:40
由指令重排序引起的可见性问题: public class Test { // 如果运行时加上 -server 下面的代码就变成了死循环,没有加就正常运行。(运行器的编译优化只有在服务器模式下才执行) // 通过设置JVM参数,打印出JIT(即时编译)编译的内容(这里说的编译不是指class文件的编译,而是指未变级别的编译) private boolean flag = true; // -server -Djava.compiler=NONE 参数可以关闭jit优化。 // 在多线程中,由于指令重排序引起的线程可见性问题。 public static void main(String[] args) throws IOException, InterruptedException { Test demo1 = new Test(); new Thread(new Runnable() { @Override public void run() { int i = 0; // class文件在运行时jit编译成为汇编指令,汇编指令出现了重排序。 /* // 重排序后的逻辑。因为while语句里面需要一直判断flag。所以jvm优化为外层使用if判断一次。 if(demo1.flag){ while (true){ i++; } } hot code : 热点代码。

蛙蛙推荐:一键定位CPU百分百问题

痞子三分冷 提交于 2020-03-30 21:19:24
摘要: 当一个.net应用在生产环境CPU突然居高不下,如何快速准确的定位问题所在,并且对实时业务影响最小化?如何不抓Dump也不用live debug就可以知道你的应用在做什么?如何确认你的应用是由于哪个线程的执行造成的CPU升高,该线程正在执行什么代码? 分析: CPU升高的原因有很多, 1、有时候应用的负载大了,CPU自然会受业务请求的增加和增高; 2、有时候因为GC回收使用了过高的CPU资源; 3、有时候是某个线程执行的代码在某种情况下陷入了死循环; 4、有时候是因为锁争用太激烈,某资源上的锁释放后,等待的线程去抢锁引起的; 5、有时候是因为线程太多,上下文切换太频繁引起的。 6、每秒抛出太多的Exception。 我们一一分析 1、我们一般会用一些计数器来观察实际的应用的负载情况和并发请求量,比如每秒接受多少请求等,所以业务量增大引起的CPU高,很容易确定。 2、GC使用的CPU百分比有专门的计数器,一看便知。 3、如果某段代码陷入了死循环引起的CPU高,只抓Dump看~*e!clrstack和!runaway还是不太好定位问题, a)、一般都是连续抓几个dump,然后用!runaway来看哪些线程的用户态时间的差很大,然后再去看该线程的调用栈。 b)、录制Thread\Thread Id和Thread\% Processor Time计数器,同时抓dump

一键定位CPU百分百问题

偶尔善良 提交于 2020-03-30 21:03:47
摘要: 当一个.net应用在生产环境CPU突然居高不下,如何快速准确的定位问题所在,并且对实时业务影响最小化?如何不抓Dump也不用live debug就可以知道你的应用在做什么?如何确认你的应用是由于哪个线程的执行造成的CPU升高,该线程正在执行什么代码? 分析: CPU升高的原因有很多, 1、有时候应用的负载大了,CPU自然会受业务请求的增加和增高; 2、有时候因为GC回收使用了过高的CPU资源; 3、有时候是某个线程执行的代码在某种情况下陷入了死循环; 4、有时候是因为锁争用太激烈,某资源上的锁释放后,等待的线程去抢锁引起的; 5、有时候是因为线程太多,上下文切换太频繁引起的。 6、每秒抛出太多的Exception。 我们一一分析 1、我们一般会用一些计数器来观察实际的应用的负载情况和并发请求量,比如每秒接受多少请求等,所以业务量增大引起的CPU高,很容易确定。 2、GC使用的CPU百分比有专门的计数器,一看便知。 3、如果某段代码陷入了死循环引起的CPU高,只抓Dump看~*e!clrstack和!runaway还是不太好定位问题, a)、一般都是连续抓几个dump,然后用!runaway来看哪些线程的用户态时间的差很大,然后再去看该线程的调用栈。 b)、录制Thread\Thread Id和Thread\% Processor Time计数器,同时抓dump

JVM-内存模型

血红的双手。 提交于 2020-03-30 19:30:43
https://www.cnblogs.com/aishangJava/p/9541920.html 原创好记性不如烂笔头_ 最后发布于2019-02-16 10:42:10 阅读数 22616 收藏 展开 运行时数据区域 程序计数器:线程私有;记录指令执行的位置;这里不会出现OutOfMemoryError 虚拟机栈:线程私有;生命周期和线程一致;存储局部变量表、操作数栈、动态链接、方法出口等信息。(局部变量表:存放了编译期可知的各种基本类型(boolean、byte、char、short、int、float、long、double)、对象引用(reference 类型)和 returnAddress 类型(指向了一条字节码指令的地址);会出现的异常:1、StackOverflowError:线程请求的栈深度大于虚拟机所允许的深度;2、OutOfMemoryError:如果虚拟机栈可以动态扩展,而扩展时无法申请到足够的内存。) 本地方法栈:线程私有;为虚拟机使用到的 Native 方法服务。也会有 StackOverflowError 和 OutOfMemoryError 异常。 堆:线程共享;JVM 所管理的内存中最大的一块区域,主要是存放对象实例和数组;会有OutOfMemoryError:如果堆中没有内存完成实例分配,并且堆也无法再扩展时,抛出该异常。 方法区:线程共享

[转] 基于XMPP协议的Android即时通信系

北慕城南 提交于 2020-03-30 18:27:08
转自:http://blog.csdn.net/lnb333666/article/details/7471292 以前做过一个基于XMPP协议的聊天社交软件,总结了一下。发出来。 设计基于开源的XMPP即时通信协议,采用C/S体系结构,通过GPRS无线网络用TCP协议连接到服务器,以架设开源的Openfn'e服务器作为即时通讯平台。 系统主要由以下部分组成:一是服务器,负责管理发出的连接或者与其他实体的会话,接收或转发XML(ExtensibleMarkup Language)流元素给授权的客户端、服务器等;二是客户终端。它与服务器相连,通过XMPP获得由服务器或任何其它相关的服务所提供的全部功能。三是协议网关。完成XMPP协议传输的信息与外部消息系统可识别信息间的翻译。再就是XMPP网络。实现各个服务器、客户端间的连接。系统采用客户端(Client)/服务端(Server)架构体系结构。 客户端: 客户端基于Android平台进行开发。负责初始化通信过程,进行即时通信时,由客户端负责向服务器发起创建连接请求。系统通过GPRS无线网络与Internet网络建立连接,通过服务器实现与Android客户端的即时通信脚。 服务器端: 服务器端则采用Openfire作为服务器。允许多个客户端同时登录并且并发的连接到一个服务器上。服务器对每个客户端的连接进行认证,对认证通过的客户端创建会话

31.Java多线程-----程序、进程、线程

試著忘記壹切 提交于 2020-03-30 17:45:07
1.程序   是为完成特定任务、用某种语言编写的一组指令的集合。即指 一段静态的代码 。 2.进程   程序的一次执行过程,或是正在运行的一个程序。 说明:进程作为 资源分配的单位 ,系统在运行时会为每个进程分配不同的内存区域 3.线程   进程可进一步细化为线程,是一个程序内部的一条执行路径。 说明:线程作为 调度和执行的单位 ,每个线程拥有独立的运行栈和程序计数器(pc),线程切换的开销小。 注意: 每个线程,拥有自己独立的:栈、程序计数器 多个线程,共享同一个进程中的结构:方法区、堆。 作者:Java之美 日期:2020-03-30 来源: https://www.cnblogs.com/897463196-a/p/12599468.html

Java面试常见知识点总结(一)

|▌冷眼眸甩不掉的悲伤 提交于 2020-03-30 16:00:55
1.sleep()和wait(): Java中的多线程是一种 抢占式 的机制,而不是分时机制。抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行。 ● 共同点 : (1) 他们都是在 多线程 的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。 (2) wait()和sleep()都可以通过 interrupt() 方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。 如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。 需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。 ● 不同点 : (1) 每个对象都有一个锁来控制同步访问。 Synchronized 关键字可以和对象的锁交互

JAVA多线程之wait/notify

…衆ロ難τιáo~ 提交于 2020-03-30 14:34:55
本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法。 ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait() 与 notify/notifyAll() 的执行过程 ③中断 调用wait()方法进入等待队列的 线程 ④notify 通知的顺序不能错 ⑤多线程中测试某个条件的变化用 if 还是用 while? ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 wait() 与 notify/notifyAll() 是Object类的方法,在执行两个方法时,要先获得锁。那么怎么获得锁呢? 在这篇: JAVA多线程之Synchronized关键字--对象锁的特点 文章中介绍了使用synchronized关键字获得锁。因此,wait() 与 notify/notifyAll() 经常与synchronized搭配使用,即在synchronized修饰的同步代码块或方法里面调用wait() 与 notify/notifyAll()方法。 ②wait() 与 notify/notifyAll() 的执行过程 由于 wait() 与 notify/notifyAll() 是放在同步代码块中的, 因此线程在执行它们时,肯定是进入了临界区中的,即该线程肯定是获得了锁的。

java中volatile,synchronized关键字

人盡茶涼 提交于 2020-03-30 12:59:54
volatile是变量修饰符,而synchronized则是作用于一段代码或方法;如下三句get代码: 1 int i1; 2 int geti1() {return i1;} 3 4 volatile int i2; 5 int geti2() {return i2;} 6 7 int i3; 8 synchronized int geti3() {return i3;} geti1() 得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。 在Java内存模型中,有main memory(主内存区域),这里存放了变量目前的“准确值”,每个线程也有自己的memory(例如寄存器)。为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。 geti2() 得到的是main

Java中关键字volatile 和 synchronized 的作用和区别

邮差的信 提交于 2020-03-30 12:59:41
volatile是变量修饰符,而synchronized则是作用于一段代码或方法 ;如下三个get方法的代码: 1 int i1; 2 int geti1() {return i1;} 3 4 volatile int i2; 5 int geti2() {return i2;} 6 7 int i3; 8 synchronized int geti3() {return i3;} geti1() 得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以相互不同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。 在Java内存模型中,有main memory(主内存区域),这里存放了变量目前的“准确值”,每个线程也有自己的memory(例如寄存器)。为了性能,一个线程会在自己的memory中保存要访问的变量的副本。这样就会出现同一个变量在某个瞬间,在一个线程的memory中的值可能与另外一个线程memory的值,或者main memory的值不一致的情况。因此实际上存在一种可能:main memory的值i1值是1,线程1里的i1是2,线程2里的i1值是3,这在线程1和线程2都改变了他们各自的i1值,而且这个改变还没来得及传给main memory 或其他线程时就会发生。 geti2() 得到的是main