线程

volatile 关键字

拟墨画扇 提交于 2020-04-04 17:53:52
摘抄并用于学习笔记 1. volatile 简介   volatile 是并发编程中另一知识点,与 Synchronized 各领风骚。   synchronized 是阻塞式同步,在线程竞争激烈的情况下会升级成重量级锁。而 volatile 就是 java 虚拟机提供的最轻量级的同步机制。Java 内存模型告诉我们,各个线程会将共享变量从主内存中拷贝到工作内存,然后执行引擎会基于工作内存中的数据进行操作处理。线程在工作内存进行操作后何时会写到主内存中?这个时机对普通变量是没有规定的,而针对 volatile 修饰的变量给 Java 虚拟机特殊的约定,线程对 volatile 变量的修改会立刻被其他线程所感知,即不会出现数据脏读的现象,从而保证数据的“可见性”。   现在我们有了一个大概的印象就是:被 volatile 修饰的变量能够保证每个线程获取该变量时是新值,从而避免出现数据脏读的现象。 2. volatile 实现原理   在生成汇编代码时会在 volatile 修饰的共享变量进行写操作的时候多出 Lock 前缀的指令。   为了提高处理速度,处理器不直接和内存进行通信,而是先将系统内存的数据读到内部缓存(L1,L2 或 其他)后再进行操作,但操作完不知道何时会写到内存。如果对声明了 volatile 的变量进行写操作,JVM 就会向处理器发送一条 Lock 前缀的指令

线程按序交替

余生长醉 提交于 2020-04-04 17:50:02
编写一个程序,开启 3 个线程,这三个线程的 ID 分别为 A、B、C, 每个线程将自己的 ID 在屏幕上打印 10 遍,要 求输出的结果必须按顺序显示 TestABCAlternate package com.aff.juc; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class TestABCAlternate { public static void main(String[] args) { AlternateDemo ad = new AlternateDemo(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 20; i++) { ad.loopA(i); } } },"A线程").start(); new Thread(new Runnable() { @Override public void run() { for (int i = 1; i <= 20; i++) { ad.loopB(i); } } },"B线程

CopyOnWriteArrayList(写入并复制) & CountDownLatch(闭锁)

…衆ロ難τιáo~ 提交于 2020-04-04 12:52:49
ConcurrentHashMap: ①Java 5.0 在 java.util.concurrent 包中提供了多种并发容器类来改进同步容器 的性能。 ② ConcurrentHashMap 同步容器类是Java 5 增加的一个线程安全的哈希表。 对与多线程的操作,介于 HashMap 与 Hashtable 之间。 内部采用“锁分段” 机制替代 Hashtable 的独占锁。进而提高性能。 ③此包还提供了设计用于多线程上下文中的 Collection 实现: ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet、 CopyOnWriteArrayList 和 CopyOnWriteArraySet。 当期望许多线程访问一个给 定 collection 时,ConcurrentHashMap 通常优于同步的 HashMap, ConcurrentSkipListMap 通常优于同步的 TreeMap。 当期望的读数和遍历远远 大于列表的更新数时,CopyOnWriteArrayList 优于同步的 ArrayList。 TestCopyOnWriteArrayList package com.aff.juc; import java.util.Iterator; import java.util

Java常用关键字总结

筅森魡賤 提交于 2020-04-04 11:40:44
1、abstract   abstract修饰类,表示抽象的意思,抽象类可以含有非抽象变量和成员变量,也可以有普通方法和构造方法,但是不能被实例化(接口),但是可以被子类继承。 public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { ... }   abstract修饰方法,表示抽象方法,抽象方法必须位于抽象类中,并且不能有具体实现。 abstract public E get(int index); 2、break   break在switch中用于跳出switch块,停止switch向下穿透的现象。 case value:expression; break;   break在循环中用于跳出循环。 while(...){ ... break; }   break也可以在后面接标签,用来跳出一些嵌套比较复杂的循环中。 flag: for(...){ for(...){ break flag; } } 3、continue   continue用于在循环中跳过本次循环。 while(...){ ... continue; }   continue也可以在后面接标签,在一些嵌套比较复杂的循环中跳过一次循环。 flag: for(...){ for(...){

tomcat线程安全问题

一个人想着一个人 提交于 2020-04-04 11:19:52
tomcat接受一个请求时,会从线程池中拿一个线程来处理这个线程,在处理的过程中会找到这个请求对应的servlet,servlet在容器中是单例的,此时如果多个请求同时请求servlet中的一些成员变量,那么就会产生线程安全问题 来源: https://www.cnblogs.com/mwss/p/12630657.html

并发编程简介

冷暖自知 提交于 2020-04-04 09:48:15
什么是并发 计算机术语中的"并发",指的是在单个系统里同时执行多个独立的活动,而不是顺序的一个接一个的执行。 对于单核CPU来说,在某个时刻只可能处理一个任务,但它却不是完全执行完一个任务再执行一个下一任务,而是一直在任务间切换,每个任务完成一点就去执行下一个任务,看起来就像任务在并行发生,虽然不是严格的同时执行多个任务,但是我们仍然称之为 并发(concurrency) 。 真正的并发是在在多核CPU上,能够真正的同时执行多个任务,称为 硬件并发(hardware concurrency) 。 并发并非没有代价,在单核CPU并发执行两个任务需要付出上下文切换的时间代价。如下图: 假设A和B两个任务都被分成10个大小相等的块,单核CPU交替的执行两个任务,每次执行其中一块,其花费的时间并不是先完成A任务再完成成B任务所花费时间的两倍,而是要更多。这是因为系统从一个任务切换到另一个任务需要执行一次 上下文切换 ,这是需要时间的(图中的灰色块)。上下文切换需要操作系统为当前运行的任务保存CPU的状态和指令指针,算出要切换到哪个任务,并为要切换的任务重新加载处理器状态。然后将新任务的指令和数据载入到缓存中。 并发的方式 多进程并发 将应用程序分为多个独立的、单线程的进程,他们可以同时运行。 这些独立的进程可以通过常规的进程间通信机制进行通信,如管道、信号、消息队列、共享内存、存储映射I

线程同步

只愿长相守 提交于 2020-04-04 06:26:56
C# 用于线程同步的方法有lock statement,Interlocked class,Monitor class,wait handles(抽象基类,后续的Mutex,Semaphore,Event均为WaitHandle的实现子类),Mutex,Semaphore,Events,ReaderWriterLockSlim,其中lock statement, Interlocked class以及Monitor class可以用于同一进程的线程间同步,而Mutex,Semaphore,Events以及ReaderWriterLockSlim可以用于不同进程的线程间同步。 lock statement : 使用C#的关键字lock进行代码区域加锁: lock (obj) //锁定引用对象实例,不能是值对象,用于对象实例级别的代码同步 { //同步代码区域 或者 lock (typeof(class)) //锁定类对象,用于类级别的静态代码同步 //同步代码区域 Interlocked class : Interlocked class是一种相对于其他同步方法更快的但只能用于变量修改同步的方法。 Interlocked class提供了以下静态方法用于同步变量的修改操作: Increment,Decrement,Exchange,CompareExchange,Add,Read

java多线程

旧城冷巷雨未停 提交于 2020-04-04 06:16:05
1、进程与线程 我们可以在计算机上运行各种计算机软件程序。每一个运行的程序可能包括多个独立运行的线程(Thread)。 线程(Thread)是一份独立运行的程序,有自己专用的运行栈。线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。 当多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制,即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。 同步这个词是从英文synchronize(使同时发生)翻译过来的。我也不明白为什么要用这个很容易引起误解的词。既然大家都这么用,咱们也就只好这么将就。 线程同步的真实意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作 。 因此,关于线程同步,需要牢牢记住的第一点是: 线程同步就是线程排队 。同步就是排队。线程同步的目的就是避免线程“同步”执行。这可真是个无聊的绕口令。 关于线程同步,需要牢牢记住的第二点是 “共享” 这两个字。 只有共享资源的读写访问才需要同步 。如果不是共享资源,那么就根本没有同步的必要。 关于线程同步,需要牢牢记住的第三点是,只有“ 变量 ”才需要同步访问。如果共享的资源是固定不变的,那么就相当于“常量”,线程同时读取常量也不需要同步。至少一个线程修改共享资源,这样的情况下,线程之间就需要同步。

线程同步概念

血红的双手。 提交于 2020-04-04 05:15:19
根据一篇文章,精简了一下关于线程同步的知识 什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致), 所以我们用同步机制来解决这些问题。 为什么要同步? 1. 线程同步=线程排队 2. 多个线程访问共享的资源才需要同步 3. 多个线程读取常量不用同步,读取变量才要同步,即涉及线程要要对数据修改才同步 4. 多个线程访问共享资源的代码有可能是同一份代码,也有可能是不同的代码;无论是否执行同一份代码,只要这些线程的代码访问同一份可变的共享资源,这些线程之间就需要同步。 如何线程同步? 1. 给共享资源的访问加同步锁(注意,为什么不是在每个对象里添加锁机制?没必要,因为同步是很耗资源的) 2. 同步锁是加在访问共享资源的代码段上的 3. 如果访问同一份共享资源,加的是不同的同步锁,并不起到同步的作用,且该同步锁没有任何意义,也就是关键要判断该锁是否是同一同步锁 4. 也就是说,同步锁本身也一定是多个线程之间的共享对象 5. 如函数体内部产生的同步锁,对于多线程不是同一个同步锁(具体看例子) 6. 任何一个Object Reference都可以作为同步锁 7. 是否是同一个同步锁,也就是看同步代码间,synchronized关键字是否使用同一个Object Reference,即同一个内存地址 8.

线程状态

☆樱花仙子☆ 提交于 2020-04-04 03:44:50
/** * 线程的状态分析 * @author aa * */ public class ThreadState { public static void main(String[] args) throws Exception { /** * 新建线程,线程为新建状态 * jdk:至今尚未启动的线程的状态。 * 如果不给线程设置名称,线程的名称将会是:Thread-0,Thread-1。。。。。 */ ThreadDemo td = new ThreadDemo() ; System.out.println("新建状态:" + td.getState()) ; // 新建状态:NEW /** * 可运行状态:当线程有资格运行,调用start方法,线程首先进入可运行状态, * 可运行状态,不一定被线程调度程序运行, * 简单来说,调用start方法后,该线程依然是可运行状态,但未运行, * 存放在可运行池中, * 线程在运行的过程中,该线程的状态也是可运行状态 * * djk:可运行线程的线程状态。处于可运行状态的某一线程正在 Java 虚拟机中运行, * 但它可能正在等待操作系统中的其他资源,比如处理器。 */ td.start() ; System.out.println("可运行状态:" + td.getState()) ; // 可运行状态:RUNNABLE /** *