线程阻塞

多线程 -- CAS自旋锁、Atomic类

廉价感情. 提交于 2020-03-18 17:01:03
1、CAS(compare and swap) CAS 概念: CAS是一种系统原语,能够原子地完成比较和交换两个动作(所谓原语属于操作系统用语范畴。原语由若干条指令组成的,用于完成一定功能的一个过程。primitive or atomic action 是由若干个机器指令构成的完成某种特定功能的一段程序,具有不可分割性·即原语的执行必须是连续的,在执行过程中不允许被中断)。CAS是Compare And Set的缩写。CAS有3个操作数,内存值V,旧的预期值E,要修改的新值N。当且仅当预期值E和内存值V相同时,将内存值V修改为B,否则什么都不做。 CAS 执行流程图: 2、自旋锁 (spinlock) 前言: 在介绍自旋锁之前,需要提到关键字 Volatile,它可以保证 JMM 模型所规定的可见性+有序性,但是它却不能保证原子性,即如果用它是不能保证对修饰变量操作的原子性的。因此不能用它来作为锁,但是它配合上 CAS 就可以构造出一种“无锁策略”的乐观自旋锁,保证了操作的原子性,而且在适合其应用的场景下效率是比较高的,因为它的优点就是可以避免线程的上下文切换所带来的系统开销。 概念: 是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。 自旋锁缺点: 1)如果某个线程持有锁的时间过长

sql语句应考虑哪些安全性?

人走茶凉 提交于 2020-03-18 08:02:58
简述项目中优化sql语句执行效率的方法,从哪些方面,sql语句性能如何分析? (1)尽量选择较小的列; (2)将where中用的比较频繁的字段建立索引; (3)select中避免使用*; (4)避免在索引列上使用计算、not in和<>等操作; (5)当只需要一行数据时候使用limit1; (6)保证单表数据不超过200w,实时分割表; 针对查询较慢的语句,可以使用explain来分析该语句具体的执行情况。 sql语句应考虑哪些安全性? (1)少使用root账户,应该为不同的动作分配不同的账户; (2)sql执行出错后,不能把数据库中显示的出错信息,直接展示给用户。防止泄露服务器和数据库相关信息; (3)防止sql注入,对特殊字符进行转义、过滤或者使用预编译的sql语句绑定变量 接下来重点说下Mysql半同步复制, 从MySQL5.5开始,MySQL以插件的形式支持半同步复制 。先来区别下mysql几个同步模式概念: 异步复制(Asynchronous replication) MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。 全同步复制(Fully synchronous

死磕 java线程系列之线程模型

北慕城南 提交于 2020-03-18 07:24:11
问题 (1)线程类型有哪些? (2)线程模型有哪些? (3)各语言使用的是哪种线程模型? 简介 在Java中,我们平时所说的并发编程、多线程、共享资源等概念都是与线程相关的,这里所说的线程实际上应该叫作“ 用户线程 ”,而对应到操作系统,还有另外一种线程叫作“ 内核线程 ”。 用户线程位于内核之上,它的管理无需内核支持;而内核线程由操作系统来直接支持与管理。几乎所有的现代操作系统,包括 Windows、Linux、Mac OS X 和 Solaris,都支持内核线程。 最终,用户线程和内核线程之间必然存在某种关系,本章我们一起来学习下建立这种关系常见的三种方法:多对一模型、一对一模型和多对多模型。 多对一模型 多对一线程模型,又叫作用户级线程模型,即多个用户线程对应到同一个内核线程上,线程的创建、调度、同步的所有细节全部由进程的用户空间线程库来处理。 优点: 用户线程的很多操作对内核来说都是透明的,不需要用户态和内核态的频繁切换,使线程的创建、调度、同步等非常快; 缺点: 由于多个用户线程对应到同一个内核线程,如果其中一个用户线程阻塞,那么该其他用户线程也无法执行; 内核并不知道用户态有哪些线程,无法像内核线程一样实现较完整的调度、优先级等; 许多语言实现的协程库基本上都属于这种方式,比如python的gevent。 一对一模型 一对一模型,又叫作内核级线程模型

进程-----线程

我的梦境 提交于 2020-03-18 06:01:29
一直来对进程,线程糊里糊涂,今天总结下: from TIPI 进程 进程是什么?进程是正在执行的程序;进程是正在计算机上执行的程序实例;进程是能分配给处理器并由处理器执行的实体。进程一般会包括指令集和系统资源集,这里的指令集是指程序代码,这里的系统资源集是指I/O、CPU、内存等。综合起来,我们也可以理解进程是具有一定独立功能的程序在关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。 在进程执行时,进程都可以被唯一的表示,由以下一些元素组成: 进程描述符:进程的唯一标识符,用来和其它进程区分。在Linux中叫进程ID,在系统调用fork期间生成,只是我们通过getpid返回的不是其pid字段,而是其线程组号tgid。 进程状态:我们常说的挂起、运行等状态,其表示的是当前的状态。 优先级:进程间的执行调度相关,相对于其它进程而言。 程序计数器:程序中即将被执行的下一条指令的地址,该地址是内核术中或用户内存空间中的内存地址。 内存指针:包括程序代码和进程相关数据的指针,还有和其它进程共享内存块的指针。 上下文数据:进程执行时处理器的寄存器的数据。 I/O状态信息:包括显式的I/O请求、分配给进程的I/O设备等 记账信息:可能包括处理器时间总和、使用的时钟数总和、时间限制等 以上的这些元素都会放在一个叫做进程控制块的数据结构中

操作系统之-进程

我的未来我决定 提交于 2020-03-17 23:03:24
一、进程    1.1 进程的含义   广义的说,进程是一个具有独立功能的程序关于某个数据集合的一次运行活动。    1.2 进程的状态   三态模型:等待态、就绪态、运行态。(五态模型比三态模型多了新建态和终止态)。--从名字可以推断各种状态的形态。    1.3 进程的特征   进程的特征有四点:动态性、并发性、独立性、异步性。   动态性--进程的实质是程序在多道程序系统中的一次执行过程,既然是过程就要有始有终,所以进程会产生、会消亡。进程执行完毕后,一般不会留下关于它运行的一丝痕迹。   并发性--任何进程都可以与其他进程一起并发执行,并发是任意时刻只有一个程序在运行(要与并行区别)。   独立性--进程是一个独立运行的基本单位,同时也是系统分配资源和调度的基本单位。   异步性--由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进。    1.4 进程的调度   进程的调度分为抢占式和非抢占式。   抢占式调度:抢过来自己占用。   无论是抢占式还是非抢占式,都要依照这个队列中任务的先后顺序来运行他们。所以,队列代表着任务的“生存周期”。只要任务还在队列中,任务就没有“死”,即没有运行结束而消亡;任务就没有“生”,即任务还未开始运行。   现在,重点就是如何安排这个队列(五种调度算法)。   以队列为基础

Java学习笔记4(多线程)

孤者浪人 提交于 2020-03-17 22:55:28
多线程 多个程序块同时运行的现象被称作 并发执行 。多线程就是指一个应用程序中有多条并发执行的线索,每条线索都被称作一条 线程 ,它们会交替执行,彼此间可以进行通信。 进程: 在一个操作系统中,每个独立执行的程序都可称作为一个进程,也就是 “正在运行的程序”。在计算机中,所有的程序都是由CPU执行的,CPU在某个时间点只能执行一个进程,在极短的时间下在不同的进程之间进行切换,给人程序在同时进行的感觉。 线程: 每个运行的程序都是一个进程,在一个进程中可以有多个执行单元同时运行,这些执行单元可以看作程序执行的一条条线索,被称为线程。多条线程看似同时执行,其实不然,它和进程一样,都是 CPU轮流执行的。 继承 Thread类创建多线程 通过继承 Thread类,并重写Thread类中的run()方法便可以实现多线程,在Thread类中提供了start()方法用于启动新线程。 class MyThread extends Thread{ //重写run()方法 public void run(){ while(true){ System.out.println("MyThread类的run()方法在运行"); } } } public class Test{ public static void main(String[] args) { MyThread myThread = new

JVM实现线程

十年热恋 提交于 2020-03-17 18:35:23
实现线程主要有三种方式:使用内核线程实现,使用用户线程实现和使用用户线程加轻量级进程混合实现。 使用内核线程实现 内核线程(KLT,Kernel-Level Thread),直接由操作系统内核(Kernel,即内核)支持的线程。由内核来完成线程切换,内核通过操纵调度器(Scheduler)对线程进行调度,并负责将线程的任务映射到各个处理器上。每个内核线程可以视为内核的一个分身,这样操作系统就有能力同时处理多件事情,支持多线程的内核叫做多线程内核。 程序一般不会去直接使用内核线程,而是去使用内核线程的一种高级接口——轻量级进程(LWP),即通常意义上的线程*。由于每个轻量级进程都由一个内核线程支持,因此只有先支持内核线程,才能有轻量级进程。*轻量级进程与内核线程之间1:1关系称为一对一的线程模型。 内核线程保证了每个轻量级进程都成为一个独立的调度单元,即时有一个轻量级进程在系统调用中阻塞了,也不会影响整个进程的继续工作。 局限:基于内核线程实现,因此各线程操作等需要系统调用,系统调用代价高,需要在用户态和内核态来回切换,其次,每个轻量级进程都需要一个内核线程的支持,因此轻量级进程要消耗一定的内核资源,如内核线程的栈空间,因此一个系统支持轻量级进程的数量是有限的。 使用用户线程实现 广义上,内核线程以外,就是用户线程。轻量级也算用户线程,但轻量级进程的实现始终是建立在内核上的

Java 多线程

╄→гoц情女王★ 提交于 2020-03-17 17:22:46
一、概述 理解多线程先要理解线程,理解线程先要理解进程。 1. 进程 一个正在执行的程序。 每个进程的执行都有一个执行的顺序,顺序是一个执行路径,也叫一个控制单元。 2. 线程 进程中独立的控制单元称为线程。 线程控制进程的执行。 进程中只要有一个线程在执行,进程就不会结束。 一个进程中至少存在一个线程。 3. 多线程 Java 虚拟机启动时,会有一个 java.exe 的执行程序,也就是一个进程。 这个进程中至少存在一个线程负责 java 程序的执行,这个线程的运行代码存在 main 方法中,这个线程称之为主线程。 JVM 启动时除了执行一个主线程,还会启动负责垃圾回收机制的线程。 在一个进程中有多个线程执行的方式,称为多线程。 4. 多线程的意义 多线程能让程序产生同时运行的效果,可以提高程序执行的效率。 例如: java.exe 进程执行主程序时,如果程序的代码非常多,在堆内存中会产生很多对象,而对象调用完后就会变成垃圾。如果垃圾过多的话,可能会导致堆内存出现内存不足的现象,影响程序的运行。这种情况下,如果只有一个线程在运行处理的话,程序执行的效率非常低;如果有多个线程在帮助处理的话,程序执行的效率将大大的提高。 例如:垃圾回收机制的线程在帮助进行垃圾回收的话,那堆内存空间的释放将快很多。 5. CPU 运行的原理 PC 上有很多程序“同时”进行,看起来好像是 CPU “同时

线程的并发工具类

。_饼干妹妹 提交于 2020-03-17 15:48:46
某厂面试归来,发现自己落伍了!>>> 1.分而治之 fork join 标准使用范畴: /** * 统计集合数据的和 */ public class ForkJoinTest1 { private static class SumTest extends RecursiveTask<Integer> { //阀值 private final static Integer THRESHOLD = MakeArray. ARRAY_LENGTH / 10 ; private int [] arry ; // 处理的数据 private int start ; //起点 private int end ; //终点 public SumTest ( int [] arry , int start , int end) { this . arry = arry ; this . start = start ; this . end = end ; } @Override protected Integer compute () { if ( end - start < THRESHOLD ) { int sum = 0 ; for ( int i= start ; i< end ; i++) { sum += arry [i] ; } return sum ; } else { int

操作系统7-信号量与管程

旧街凉风 提交于 2020-03-17 15:31:59
回顾一下 : 并发问题:多线程并发导致资源竞争 同步概念: ---------1. 协调多线程对 共享数据 的访问 ---------2.任何时刻只能由一个线程执行临界区代码 确保同步正确的方法 ---------底层硬件支持 ---------高层次的编程抽象( 锁 ) 信号量是锁机制在同一层上的高层抽象编程方法 一、 信号量semaphore 信号量是操作系统提供的一种 协调共享资源访问 的方法, 用信号量表示系统资源的数量 信号是一种抽象数据类型,由一个整型(sem)变量和两个原子操作组成: 1)P():sem减1,如sem<0,表示申请资源(减1)后没有资源了,需要等待 2)V():sem加1,如sem<=0,即一个资源用完(加1)但还是小于0表示还有资源在等待,那么就唤醒一个等待进程 信号量是被保护的整数变量。初始化完成后就只能通过P()和V()操作来修改,并且由操作系统来保证PV操作时原子操作 P可能由于没有资源而进入阻塞状态,但是V操作不会被阻塞 假定信号量实现的同步是公平的,线程不会被阻塞在P()操作中,并且信号量等待按先进先出 信号量的实现 class Semophore { int sem ; WaitQueue q ; } Semophore :: P ( ) { sem -- ; //申请一个资源 if ( sem < 0 ) //资源不够,要等待 {