线程

原子操作类AtomicInteger详解

生来就可爱ヽ(ⅴ<●) 提交于 2020-03-20 08:08:13
为什么需要AtomicInteger原子操作类? 对于Java中的运算操作,例如自增或自减,若没有进行额外的同步操作,在多线程环境下就是线程不安全的。num++解析为num=num+1,明显,这个操作不具备原子性,多线程并发共享这个变量时必然会出现问题。测试代码如下: public class AtomicIntegerTest { private static final int THREADS_CONUT = 20; public static int count = 0; public static void increase() { count++; } public static void main(String[] args) { Thread[] threads = new Thread[THREADS_CONUT]; for (int i = 0; i < THREADS_CONUT; i++) { threads[i] = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 1000; i++) { increase(); } } }); threads[i].start(); } while (Thread.activeCount() > 1) {

原子操作类AtomicInteger详解

谁说我不能喝 提交于 2020-03-20 08:08:00
为什么需要AtomicInteger原子操作类? 对于Java中的运算操作,例如自增或自减,若没有进行额外的同步操作,在多线程环境下就是线程不安全的。num++解析为num=num+1,明显,这个操作不具备原子性,多线程并发共享这个变量时必然会出现问题。测试代码如下: public class AtomicIntegerTest { private static final int THREADS_CONUT = 20; public static int count = 0; public static void increase() { count++; } public static void main(String[] args) { Thread[] threads = new Thread[THREADS_CONUT]; for (int i = 0; i < THREADS_CONUT; i++) { threads[i] = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 1000; i++) { increase(); } } }); threads[i].start(); } while (Thread.activeCount() > 1) {

ConcurrentHashMap源码解析(1.8)

末鹿安然 提交于 2020-03-20 07:58:47
一、简介 上篇文章 详细介绍了HashMap的源码及原理,本文趁热打铁继续分析ConcurrentHashMap的原理。 首先在看本文之前,希望对HashMap有一个详细的了解。不然看直接看ConcurrentHashMap的源码还是有些费劲的。 相信对HashMap,HashTable有一定了解,应该知道HashMap是不具备线程安全性的,在resize时会丢数据(JDK8),而HashTable虽然保证了线程安全性,但是其是通过给每个方法加Synchronized关键字达到的同步目的。但是都知道Synchronized在竞争激烈的多线程并发环境中,在性能上的表现是非常不如人意的。那在高并发环境中HashMap如何保证线程安全而又不浪费太多性能呢?答案就是Java J.U.C并发包中的ConcurrentHashMap。 依然开局一张图。JDK8中的ConcurrentHashMap数据结构。 呃呵,和HashMap的结构是一样的,没错在数据结构层面,ConcurrentHashMap和HashMap是完全一样的。有了这个基础继续往下看。 二、历史版本 ConcurrentHashMap的历史版本大致分界线在JDK8。也就是可以分为JDK8和JDK8以前版本。 数据结构的区别 在JDK8之前HashMap没有引入红黑树,同样的ConcurrentHashMap也没有引入红黑树

[读书笔记]《Effective Java》第10章并发

回眸只為那壹抹淺笑 提交于 2020-03-20 07:44:06
第66条:同步访问共享的可变数据 同步的意义。 正确地使用同步可以保证没有任何方法会看到对象处于不一致的状态中。 进入同步方法或者同步代码块的每个线程,都看到由同一个锁保护的之前所有的修改效果。 Java语言规范保证读或者写一个变量是原子的,除非这个变量的类型为long或者double。 对于原子数据的读取,Java语言规范并不保证一个线程写入的值对于另一个线程将是可见的。 对于共享的数据,即使数据是原子可读写的,也要使用同步。 活动性失败:因为JVM的优化,部分代码无法执行。 1 /** 2 * 共享原子可读写的变量不使用同步访问. 3 * Created by itlivemore on 17-7-1. 4 */ 5 public class StopThread { 6 private static boolean stopThread; 7 8 public static void main(String[] args) throws InterruptedException { 9 Thread backGroundThread = new Thread(new Runnable() { 10 @Override 11 public void run() { 12 int i = 0; 13 while (!stopThread) { 14 System.out

使用AsyncTask类实现简单的异步处理操作

本小妞迷上赌 提交于 2020-03-20 05:03:36
AsyncTask: 1.这是一种相比Handler更轻量级的处理异步任务的工具类 2.它和Handler类一样,都是为了不影响主线程(UI)而使用的((注:UI的更新只能在主线程中完成) 3.这个工具类提供了三个泛型的参数: params:启动或执行任务的输入参数,例如:HTTP请求的URL Progress:后台任务执行的百分比 Result:后台执行任务最终返回的结果,比如String 使用AsyncTask最少要重写这两个方法: 1.doInBackground(params··)   此方法在后台执行,比较耗时的操作都可以放在这里执行;   这里不能直接操作UI(主线程),此方法在后台线程执行;完成任务的主要工作,通常需要很长世间;   在此执行过程中可以调用publishProgress()来更新工作进度。 2.onPostExecute(Result)   相当于Handler处理UI的方式;   可以使用在doInBackground得到的结果处理和操作UI;   此方法在主线程中执行,任务执行的结果作为参数的返回。 如果有必要还可以重写一下三个方法: onProgressUpdate();   这里可以使用进度条来显示任务执行的进度情况,用来增加用户体验。(此方法在主线程中执行) onPreExecute();   这里是用户调用Execute的接口

Linux 多线程通信

岁酱吖の 提交于 2020-03-20 04:45:10
摘自资料(linux 与Windows不同) 线程间无需特别的手段进行通信,由于线程间能够共享数据结构,也就是一个全局变量能够被两个线程同一时候使用。只是要注意的是线程间须要做好同步,一般用mutex。能够參考一些比較新的UNIX/Linux编程的书,都会提到Posix线程编程,比方《UNIX环境高级编程(第二版)》、《UNIX系统编程》等等。 linux的消息属于IPC,也就是进程间通信,线程用不上。 linux用pthread_kill对线程发信号。 另:windows下不是用post..(你是说PostMessage吗?)进行线程通信的吧? windows用PostThreadMessage进行线程间通信,但实际上极少用这样的方法。还是利用同步多一些 LINUX下的同步和Windows原理都是一样的。只是Linux下的singal中断也非常好用。 用好信号量,共享资源就能够了。 使用多线程的理由之中的一个是和进程相比,它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而执行于一个进程中的多个线程,它们彼此之间使用同样的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,并且

【JUC】JDK1.8源码分析之ReentrantLock(三)

你。 提交于 2020-03-20 03:44:15
一、前言   在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看ArrayBlockingQueue源码会很容易,下面开始正文。 二、ArrayBlockingQueue数据结构   通过源码分析,并且可以对比ArrayList可知,ArrayBlockingQueue的底层数据结构是数组,数据结构如下   说明:ArrayBlockingQueue底层采用数据才存放数据,对数组的访问添加了锁的机制,使其能够支持多线程并发。 三、ArrayBlockingQueue源码分析    3.1 类的继承关系    public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {}   说明:可以看到ArrayBlockingQueue继承了AbstractQueue抽象类,AbstractQueue定义了对队列的基本操作;同时实现了BlockingQueue接口,BlockingQueue表示阻塞型的队列,其对队列的操作可能会抛出异常;同时也实现了Searializable接口,表示可以被序列化。   

iOS runloop初步学习

China☆狼群 提交于 2020-03-20 03:05:04
参考: http://www.aichengxu.com/view/4329711 1. 定义: 其实它内部就是do-while循环,在这个循环内部不断地处理各种任务(比如Source、Timer、Observer),能让线程不被系统终止 一个线程对应一个RunLoop,主线程的RunLoop默认已经启动,子线程的RunLoop得手动启动(调用run方法) RunLoop只能选择一个Mode启动,如果当前Mode中没有任何Source(Sources0、Sources1)、Timer,那么就直接退出RunLoop runloop常用的三种模式: NSDefaultRunLoopMode:runloop默认的模式,程序启动模式主线程的runloop就是在NSDefaultRunLoopMode模式下运行的。 UITrackingRunLoopMode:runloop在用户点击或触摸屏幕时,会自动切换到该模式。 NSRunLoopCommonModes:指标记为common modes的所有模式,即前两者的集合。 2. 作用 可以使用runloop, 在一个子线程中长期监控某个事件 - (void)viewDidLoad { [super viewDidLoad]; // 开启一个线程让它执行run方法,如果run方法过了,线程就会死掉 self.thread = [[NSThread

RunLoop 总结及应用

纵饮孤独 提交于 2020-03-20 03:04:20
什么是RunLoop 注释:和ppt上总结的一样 和代码一块去理解 从字面上看 运行循环 跑圈 循环 基本作用 保持程序的持续运行(比如主运行循环) 处理App中的各种事件(比如触摸事件、定时器事件、Selector事件) 节省CPU资源,提高程序性能:该做事时做事,该休息时休息 存在价值 没有RunLoop 有RunLoop main函数中的RunLoop(主运行循环) 主运行循环 第14行代码的UIApplicationMain函数内部就启动了一个RunLoop 所以UIApplicationMain函数一直没有返回,保持了程序的持续运行 这个默认启动的RunLoop是跟主线程相关联的 RunLoop对象 iOS中有2套API来访问和使用RunLoop Foundation NSRunLoop Core Foundation CFRunLoopRef NSRunLoop和CFRunLoopRef都代表着RunLoop对象 NSRunLoop是基于CFRunLoopRef的一层OC包装,所以要了解RunLoop内部结构,需要多研究CFRunLoopRef层面的API(Core Foundation层面) RunLoop资料 苹果官方文档 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual

多线程 NSThread

霸气de小男生 提交于 2020-03-20 03:03:47
多线程 NSThread 创建和启动线程 一个NSThread对象就代表一条线程 创建、启动线程 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; [thread start]; // 线程一启动,就会在线程thread中执行self的run方法 主线程相关用法 + (NSThread *)mainThread; // 获得主线程 - (BOOL)isMainThread; // 是否为主线程 + (BOOL)isMainThread; // 是否为主线程 其他用法 获得当前线程 NSThread *current = [NSThread currentThread]; 线程的调度优先级 + (double)threadPriority; + (BOOL)setThreadPriority:(double)p; - (double)threadPriority; - (BOOL)setThreadPriority:(double)p; 调度优先级的取值范围是0.0 ~ 1.0,默认0.5,值越大,优先级越高 线程的名字 - (void)setName:(NSString *)n; - (NSString *)name; 其他创建线程方式