atomic

Java多线程编程基础知识汇总

穿精又带淫゛_ 提交于 2020-08-13 05:26:47
多线程简介 多任务   现代操作系统(Windows、Linux、MacOS)都可以执行多任务,多任务就是同时运行多个任务。例如在我们的计算机上,一般都同时跑着多个程序,例如浏览器,视频播放器,音乐播放器,Word办公软件等等,由于CPU执行代码都是一条一条顺序执行的,即时是单核CPU也可以同时执行多个任务,操作系统执行多个任务实际上就是轮流让多个任务交替执行。即使是多核CPU,因为通常任务的数量是远多于CPU的核数,所以任务也是交替执行的。 进程(Process)   在计算机中,我们把一个任务称为一个进程。浏览器就是一个进程,视频播放器是另外一个进程,音乐播放器也是一个进程,在某些进程内部还需要同时执行多个子任务。例如我们在使用Word时,在打字的同时需要进行拼写检查,还可以在后台进行打印,我们把子任务称为线程。 进程和线程的关系: 一个进程可以包含一个或多个线程(至少包含一个线程) 线程是操作系统调度的最小任务单位 如何调度线程完全由操作系统决定(程序自己不能决定线程何时执行,执行多长时间) 实现多任务的三种方法: 多进程模式(每个进程只有一个线程) 多线程模式(一个进程有多个线程) 多进程+多线程(复杂度最高) 多进程和多线程的对比: 创建进程比创建线程开销大(尤其是在Windows系统上) 进程间通信比线程间通信慢 多进程稳定性比多线程高(因为在多进程的情况下

总结:iOS中多线程的经典崩溃

妖精的绣舞 提交于 2020-08-12 10:51:37
前言 iOS崩溃是让iOS开发人员比较头痛的事情,app崩溃了,说明代码写的有问题,这时如何快速定位到崩溃的地方很重要。调试阶段是比较容易找到出问题的地方的,但是已经上线的app并分析崩溃报告就比较麻烦了。 本文将给大家总结介绍关于iOS中多线程的一些经典崩溃,下面话不多说了,来一起看看详细的介绍吧。 Block 回调的崩溃 在MRC环境下,使用Block 来设置下载成功的图片。当self释放后,weakSelf变成野指针,接着就悲剧了 __block ViewController *weakSelf = self; [self.imageView imageWithUrl:@"" completedBlock:^(UIImage *image, NSError *error) { NSLog(@"%@",weakSelf.imageView.description); }]; 多线程下Setter 的崩溃 Getter & Setter 写多了,在单线程的情况下,是没有问题的。但是在多线程的情况下,可能会崩溃。因为[_imageView release]; 这段代码可能会被执行两次,oops! UIKit 不是线程,所以在不是主线程的地方调用UIKit 的东西,有可能在开发阶段完全没问题,直接免测。但是一到线上,崩溃系统可能都是你的崩溃日志。Holy shit! 解决办法

Java线程基础回顾及内存模型,看你还记得多少?

天涯浪子 提交于 2020-08-12 08:59:58
线程创建的两种方式 继承Thread类 class MyThread extends Thread{ ...... @Override public void run (){ ...... } } MyThread mt = new MyThread(); //创建线程 mt.start(); //启动线程 复制代码 实现Runnable接口 class MyThread implements Runnable{ ...... @Override public void run (){ ...... } } MyThread mt = new MyThread(); //创建Runnable对象 Thread td = new Thread(mt); //创建线程 td.start(); //启动线程 复制代码 两种方式的区别: 1.继承Thread类受限于JAVA单继承的特性,而实现Runnable接口则没有这种限制; 2.Runnable的代码可以被多个Thread共享,适用于多个线程处理同一资源(同一个Runnable对象)的情形。 线程的生命周期 创建 new一个线程对象。 就绪 创建线程之后,调用了start()方法,此时线程进入就绪队列,等待CPU调度。或者阻塞状态的线程被唤醒。 运行 获取到了CPU资源,执行run()方法。 终止 线程的run()方法执行完毕

99 道 Java 多线程面试题,看完我跪了!

孤人 提交于 2020-08-12 05:52:47
今天给大家更新的是一篇关于多线程面试的文章,是根据时下热门的面试内容给大家进行总结的,如有雷同,请多见谅。 本篇文章属于干货内容!请各位读者朋友一定要坚持读到最后,完整阅读本文后相信你对多线程会有不一样感悟,下次面试和面试官也能杠一杠相关内容了。 1.什么是进程? 进程是系统中正在运行的一个程序,程序一旦运行就是进程。 进程可以看成程序执行的一个实例。进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间。一个进程无法访问另一个进程的变量和数据结构,如果想让一个进程访问另一个进程的资源,需要使用进程间通信,比如管道,文件,套接字等。 2.什么是线程? 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 3.线程的实现方式? 1.继承Thread类 2.实现Runnable接口 3.使用Callable和Future 4.Thread 类中的start() 和 run() 方法有什么区别? 1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。然后通过此Thread类调用方法run(

芯片Timing sign-off Corner理解

纵然是瞬间 提交于 2020-08-12 05:07:21
参考博文:http://blog.sina.com.cn/s/blog_5ced60e80102y7pd.html 一颗健壮的IC芯片应该具有能屈能伸的品质,他需要适应于他所在应用范围内变化的温度、电压,他需要承受制造工艺的偏差,这就需要在设计实现过程中考虑这些变化的温度、电压和工艺偏差。 在STA星球,用 library PVT、RC corner跟OCV 来模拟这些不可控的随机因素。在每个工艺结点,通过大量的建模跟实测,针对每个具体的工艺,foundary厂都会提供一张推荐的timingsignoff表格, 建议需要signoff的corner及各个corner需要设置的ocv跟margin。这些corner能保证大部分芯片可以承受温度、电压跟工艺偏差,一个corner=libraryPVT+ RC corner + OCV,本文将关注于library PVT。 ------OCV(on-chip-variation)也是用来模拟cell的PVT及线的RC变化,与前面两个不同的是,前两者是芯片全局的PVT/RC Corner,OCV是芯片上内的局部偏差(包括process 、 voltage、temperature、network RC)。比如在STA分析setup时,并不是用最慢的library PVT来signoff就是最差情况,对于capture

JAVA多线程基础学习三:volatile关键字

我的未来我决定 提交于 2020-08-11 20:12:32
Java的volatile关键字在JDK源码中经常出现,但是对它的认识只是停留在共享变量上,今天来谈谈volatile关键字。 volatile,从字面上说是易变的、不稳定的,事实上,也确实如此,这个关键字的作用就是告诉编译器,只要是被此关键字修饰的变量都是易变的、不稳定的。那为什么是易变的呢?因为volatile所修饰的变量是直接存在于主内存中的,线程对变量的操作也是直接反映在主内存中,所以说其是易变的。 一、Java内存模型 Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。如下图: 看个例子: public class VolatileExample extends Thread{ // 设置类静态变量,各线程访问这同一共享变量 private static boolean flag = false ; // 无限循环,等待flag变为true时才跳出循环 public void run() { while (! flag){ }; System.out.println( "停止了" ); } public static void main(String[] args) throws

Java操作Redis之Jedis用法详解

大兔子大兔子 提交于 2020-08-11 01:45:11
Redis(Remote Dictionary Server,远程数据字典服务器)是一个开源的高性能内存数据库,常用作缓存服务器使用,也做消息队列使用。因其高性能、丰富的数据类型、可扩展等特性受开发者青睐,这里介绍在java中使用Jedis操作Redis的基本用法。 1. 字符串String。 package com.zws.redis.examples; import java.util.concurrent.TimeUnit; import redis.clients.jedis.Jedis; public class RedisString { public static void main(String[] args) throws InterruptedException { String host = "192.168.137.131"; int port = 6379; String password = "redis"; Jedis jedis = new Jedis(host, port); jedis.auth(password); jedis.ping(); jedis.set("name", "张三"); //设置 jedis.set("age", "23"); String name = jedis.get("name");//获取 String age

【漫画】JAVA并发编程 如何解决原子性问题

偶尔善良 提交于 2020-08-10 18:40:55
在 并发编程BUG源头 文章中,我们初识了并发编程的三个bug源头:可见性、原子性、有序性。在 如何解决可见性和原子性 文章中我们大致了解了可见性和有序性的解决思路,今天轮到最后一个大bug,那就是原子性。 知识回顾 锁模型 JAVA中的锁模型 锁是一种通用的技术方案,Java 语言提供的 synchronized 关键字,就是锁的一种实现。 synchronized 是独占锁/排他锁(就是有你没我的意思),但是注意!synchronized并不能改变CPU时间片切换的特点,只是当其他线程要访问这个资源时,发现锁还未释放,所以只能在外面等待。 synchronized一定 能保证原子性 ,因为被 synchronized 修饰某段代码后,无论是单核 CPU 还是多核 CPU,只有一个线程能够执行该代码,所以一定能保证原子操作 synchronized也 能够保证可见性和有序性 。根据前第二篇文章:Happens-Before 规则之管程中锁的规则:对一个锁的解锁 Happens-Before 于后续对这个锁的加锁。即前一个线程的解锁操作对后一个线程的加锁操作可见。综合 Happens-Before 的传递性原则,我们就能得出前一个线程在临界区修改的共享变量(该操作在解锁之前),对后续进入临界区(该操作在加锁之后)的线程是可见的。- synchronized

原子性操作原理分析

血红的双手。 提交于 2020-08-10 12:57:44
1. 概念 原子操作是指不被打断的操作,即它是最小的执行单位。最简单的原子操作就是一条条的汇编指令(不包括一些伪指令,伪指令会被汇编器解释成多条汇编指令)。在 linux 中原子操作对应的数据结构为 atomic_t,定义如下: typedef struct { int counter; } atomic_t; 本质上就是一个整型变量,之所以定义这么一个数据类型,是为了让原子操作函数只接受 atomic_t 类型的操作数,如果传入的不是 atomic_t 类型数据,在程序编译阶段就不会通过;另一个原因就是确保编译器不会对相应的值进行访问优化,确保对它的访问都是对内存的访问,而不是对寄存器的访问。 2. 赋值操作 ARM 处理器有直接对内存地址进行赋值的指令(STR)。 #define atomic_set(v,i) (((v)->counter) = (i)) 3. 读操作 用 volatile 来防止编译器对变量访问的优化,确保是对内存的访问,而不是对寄存器的访问。 #define atomic_read(v) (*(volatile int *)&(v)->counter) 4. 加操作 使用独占指令完成累加操作。 static inline void atomic_add(int i, atomic_t *v) { unsigned long tmp; int result;

Java-volatile

允我心安 提交于 2020-08-09 21:07:24
volatile解决了线程间共享变量的可见性问题。 使用volatile会增加性能开销。 volatile并不能解决线程同步问题。 i++自增变量是非线程安全的,解决i++或者++i这样的线程同步问题需要使用synchronized或者AtomicXX系列的包装类,同时也会增加性能开销。 java.util.concurrent.atomic.AtomicInteger; 来源: oschina 链接: https://my.oschina.net/ZRYACOOL/blog/4465186