线程

操作系统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 ) //资源不够,要等待 {

java

守給你的承諾、 提交于 2020-03-17 13:24:28
1、CAS Conmpare And Swap比较和交换,主要用于多个线程对共享内存的变量(全局变量)操作时的线程安全问题。它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。这是作为单个原子操作完成的。 一个 CAS 涉及到以下操作 我们假设内存中的原数据V,旧的预期值A(线程从共享内存中取出的数据),需要修改的新值B。 比较 A 与 V 是否相等。(比较) 如果比较相等,将 B 写入 V。(交换) 返回操作是否成功。 当多个线程同时对某个资源进行CAS操作,只能有一个线程操作成功,但是并不会阻塞其他线程,其他线程只会收到操作失败的信号。可见 CAS其实是一个乐观锁。 下图中,主存中保存V值,线程中要使用V值要先从主存中读取V值到线程的工作内存A中,然后计算后变成B值,最后再把B值写回到内存V值中。多个线程共用V值都是如此操作。CAS的核心是在将B值写入到V之前要比较A值和V值是否相同,如果不相同证明此时V值已经被其他线程改变,重新将V值赋给A,并重新计算得到B,如果相同,则将B值赋给V。 ABA 问题 CAS 由三个步骤组成,分别是“读取->比较->写回”。 考虑这样一种情况,线程1和线程2同时执行 CAS 逻辑,两个线程的执行顺序如下: 时刻1:线程1执行读取操作,获取原值 A,然后线程被切换走 时刻2:线程2执行完成 CAS

zookeeper实现分布式锁

╄→尐↘猪︶ㄣ 提交于 2020-03-17 11:53:15
思考:分布式锁实现的逻辑 1.争抢锁,只有一个线程可以获得锁。 2.获得锁的线程挂了,产生死锁。解决:使用临时节点(伴随客户端的session,session删除时临时节点也会删除)。 3.获得锁的线程执行成功,释放锁。 4.上面两点,锁被删除或者释放,其他线程如何知道。 (1.主动轮询,弊端:延迟,压力 。 2.watch,解决延迟问题,弊端:压力) 5.sequence(序列节点) + watch:watch前一个,最小的获得锁,一旦最小的释放锁,只给watch他的那个发事件回调。 public class WatchCallBack implements Watcher ,AsyncCallback.StringCallback ,AsyncCallback.Children2Callback ,AsyncCallback.StatCallback { ZooKeeper zk ; String threadName; CountDownLatch cc = new CountDownLatch(1); String pathName; public String getPathName() { return pathName; } public void setPathName(String pathName) { this.pathName = pathName; }

使用MySQL SQL线程回放Binlog实现恢复

Deadly 提交于 2020-03-17 11:48:34
目录 1. 需求部分 1.1 基于MySQL复制同步特性,尝试使用Replication的SQL线程来回放binlog,可基于以下逻辑模拟场景 1.2 基于题目1.1,考虑是否可以做到以下场景的恢复 2.操作部分 2.1 环境准备及故障模拟 2.2 数据恢复 2.3 只恢复单个库的数据 2.4 只恢复单个表的数据 2.5 恢复到指定的GTID或position点 2.6 提升恢复效率的参数优化 2.7 使用复制线程与使用mysqlbinlog恢复的效率对比 2.8 总结 1. 需求部分 1.1 基于MySQL复制同步特性,尝试使用Replication的SQL线程来回放binlog,可基于以下逻辑模拟场景 做全量xtrabackup备份模拟日常备份 执行sysbench压测4张表,20个线程,压测10分钟,模拟大量binlog 删除实例模拟数据库被误删除或硬件故障(binlog需要保留) 使用xtrabackup恢复全量备份 使用MySQL Replication SQL线程回放binlog(提示:恢复前需要将relay_log_recocery参数设置为0) 1.2 基于题目1.1,考虑是否可以做到以下场景的恢复 只恢复单个库的数据 只恢复单个表的数据 将数据恢复到指定的GTID或者position点(如恢复到误操作drop之前的GTID) 是否可以通过参数调整提升回放效率

Java NIO概述

故事扮演 提交于 2020-03-17 11:44:04
传统的输入输出流都是阻塞的输入输出。举个列子:当用传统的流进行数据输入时,如果流中没有数据,它会阻塞当前线程往下执行,等到从流中读到数据为止。另外传统的输入输出流每次处理的是一个字节或一个字符,通常效率不是很高。从JDK 1.4开始 Java提供了NIO功能,可以代替传统的输入输出功能,在效率上也有很大提升。 标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中(双向操作)。NIO可以使用非阻塞模式。 NIO概述 NIO在处理文件时会将文件的一段区域直接映射到内存中,这样访问文件时就可以像访问内存一样,比传统的输入输出要快很多 。主要的实现类都在java.nio下面。 Channe l和 Buffer 是NIO中两个核心的概念。Channel的概念和传统的InputStram和OutputStream对标,最大的区别是Channel提供了一个map()方法将文件的块数据映射到内存中。可以面向一大块数据进行处理。Buffer可以理解成缓冲,其本质是一个数组。从Channel中读出来的数据要先存在Buffer中,要写到Channel中的数据也要先放到Buffer中。 另外,NIO还提供了将Unicode字符串映射成字节序列的Charset类

线程同步synchronized

六眼飞鱼酱① 提交于 2020-03-17 11:41:01
同步条件:等待池序列,锁机制。 由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突的问题。为了保证数据在方法中被访问时的正确性,在访问时加入锁机制(synchronized),当一个线程获得对象的排它锁,独占资源,其他线程必须等待,使用后释放锁即可。存在以下问题: 一个线程持有锁会导致其它所有需要此锁的我程挂起; 在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题: 如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能问题。 可以 修饰方法或者代码块 ,确保多个线程在同一时刻,只能有一个线程处理方法或者是同步块,Synchronized修饰的方法或者代码块相当于并发中的临界区,在同一时刻JVM只允许一个线程进入执行。 保证线程对访问变量的可见性,有序性,原子性 。 修饰普通方法 修饰静态方法 修饰代码块 通过synchronized关键字来处理统计1秒钟count++的次数 public class SynchronizedDemo { private static boolean flag = true; public static void main(String[] args) { Thread thread = new Thread(new Runnable() { @Override public

JAVA并发编程-线程间协作(Object监视器方法与Condition)

二次信任 提交于 2020-03-17 11:21:32
某厂面试归来,发现自己落伍了!>>> 原文地址: http://blog.csdn.net/zhshulin/article/details/50762465 下面只是简单的介绍一下,具体代码可以看我分享的代码,注释都有 说到线程间协作,不得不提到经典的 生产者与消费者模型 :有一个商品队列,生产者想队列中添加商品,消费者取出队列中的商品;显然,如果队列为空,消费者应该等待生产者产生商品才能消费;如果队列满了,生产者需要等待消费者消费之后才能生产商品。队列就是这个模型中的临界资源,当队列为空时,而消费者获得了该对象的锁,如果不释放,那么生产者无法获得对象锁,而消费者无法消费对象,就进入了死锁状态;反之队列满时,生产者不释放对象锁也会造成死锁。这是我们不希望看到的,所以就有了线程间协作来解决这个问题。 其实说到生产者与消费者模型,我们不能简单的知道怎么实现,而是需要知这种模型的使用场景:主要是为了复用和解耦, 常见的消息框架(非常经典的一种生产者消费者模型的使用场景) ActiveMQ 。发送端和接收端用Topic进行关联。 JAVA语言中,如何实现线程间协作呢?比较常见的方法就是利用Object.wait(),Object.notify()和Condition。 先看看这几个方法究竟有什么作用?为什么利用它们就可以实现线程间协作了呢? 首先分析一下wait()/notify()

ThreadLocal原理

感情迁移 提交于 2020-03-17 11:06:04
ThreadLocal作用 ThreadLocal是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有在指定的线程中可以获取到存储的数据,对于其他线程来说则无法取到数据。 ThreadLocal源码 // Thread类中持有ThreadLocalMap,这个ThreadLocalMap里的Entry是继承WeakReference,hash冲突解决法是 开放地址法 ThreadLocal . ThreadLocalMap threadLocals = null ; // 由于ThreadLocalMap是跟随着具体的线程,所以自然get()时是获取当前线程的东西不会获取其他线程的数据。 public T get ( ) { Thread t = Thread . currentThread ( ) ; ThreadLocalMap map = getMap ( t ) ; if ( map != null ) { // 以自身为key,因为一个线程可以存多个不同的ThreadLocal的东西 ThreadLocalMap . Entry e = map . getEntry ( this ) ; if ( e != null ) { @SuppressWarnings ( "unchecked" ) T result = ( T ) e . value

Java Grammar(三):修饰符

风格不统一 提交于 2020-03-17 09:21:36
简介 修饰符是用于限定类型以及类型成员申明的一种符号,从修饰对象上可以分为类修饰符,方法修饰符,变量修饰符;从功能上可以划分为访问控制修饰符和非访问修饰符。访问修饰符控制访问权限,不同的访问修饰符有不同的权限范围,而非访问修饰符则是提供一些特有功能。 下面我们从功能的角度分别讲解修饰符 访问修饰符 访问修饰符有四种: public , private , protected , default 。这里需要注意,我们这里的 default 和非访问修饰符中的 default 可不是一个东西! 这里的 default 指的是默认, 什么也不写 ,在同一包内可见,不使用任何修饰符。使用对象: 类、接口、变量、方法 。 private 指的是在仅仅在类内可见,所以也就很好理解, private 只能修饰 方法,变量 ,而不能修饰类和接口(毕竟你只能类内访问,你修饰类谁能看得到呢?),修饰方法的时候,一般用于我们在重构代码的时候提取公用代码为 内部实现方法 ,修饰变量的情景相比我们就经常见到了,由于Java的 封装 特性,我们在定义一个类的时候,经常会把该类的属性定义为 private ,通过 get or set 方法来访问这些变量。 而 public 在我们日常中使用的比较多,我们经常会把类声明为 public ,声明成 public 的 类,接口,变量,方法 可以被任何类访问

Java内存模型

非 Y 不嫁゛ 提交于 2020-03-17 08:59:43
Java内存模型 原本准备把内存模型单独放到某一篇文章的某个章节里面讲解,后来查阅了国外很多文 档才发现其实JVM内存模型的内容还蛮多的,所以直接作为一个章节的基础知识来讲解,可能该章节概念的东西比较多。一个开发Java的开发者,一旦了解了 JVM内存模型就能够更加深入地了解该语言的语言特性,可能这个章节更多的是概念,没有太多代码实例,所以希望读者谅解,有什么笔误来Email告知: silentbalanceyh@126.com , 本文尽量涵盖所有Java语言可以碰到的和内存相关的内容,同样也会提到一些和内存相关的计算机语言的一些知识,为草案。因为平时开发的时候没有特殊情况 不会进行内存管理,所以有可能有笔误的地方比较多,我用的是Windows平台,所以本文涉及到的与操作系统相关的只是仅仅局限于Windows平台。不 仅仅如此,这一个章节牵涉到的多线程和另外一些内容并没有讲到,这里主要是结合JVM内部特性把本章节作为核心的概念性章节来讲解,这样方便初学者深入以 及彻底理解Java语言) 本文章节: 1.JMM简介 2.堆和栈 3.本机内存 4.防止内存泄漏 1.JMM简介    i.内存模型概述   Java平台自动集成了 线程 以及 多处理器技术 ,这种集成程度比Java以前诞生的计算机语言要厉害很多,该语言针对 多种异构平台的平台独立性