线程

乐观锁与悲观锁

早过忘川 提交于 2020-03-14 07:55:19
一乐观锁 总是认为不会产生并发问题,每次去取数据的时候总认为不会有其他线程对数据进行修改,因此不会上锁,但是在更新时会判断其他线程在这之前有没有对数据进行修改,一般会使用版本号机制或CAS操作实现。 version方式:一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。 核心SQL代码: update table set x=x+1, version=version+1 where id=#{id} and version=#{version}; CAS操作方式:即compare and swap 或者 compare and set,涉及到三个操作数,数据所在的内存值,预期值,新值。当需要更新时,判断当前内存值与之前取到的值是否相等,若相等,则用新值更新,若失败则重试,一般情况下是一个自旋操作,即不断的重试。 二悲观锁 总是假设最坏的情况,每次取数据时都认为其他线程会修改,所以都会加锁(读锁、写锁、行锁等),当其他线程想要访问数据时,都需要阻塞挂起。可以依靠数据库实现,如行锁、读锁和写锁等,都是在操作之前加锁,在Java中

读写锁分离的循环队列

空扰寡人 提交于 2020-03-14 05:21:05
在很多需要高性能的场合下,锁的设计一直是一个比较关键的问题。无锁队列、读写锁分离的队列在业界以及学术界都已经有很成熟的研究。在网上也有很多资料, 但其实有很多实现都是错误的 。最近在工作中帮忙追查一个线上问题时,就发现实现一个正确的版本是比较困难的事情。 背景:实现一个循环队列,队列长度已预先分配。支持不同线程的多写多读。 原本的实现是对读和写分别使用了两个不同的锁来提升性能,但是在最早实现的时候 并没有发现到 线程间数据的同步修改会造成小概率读取脏数据 导致线上服务有问题 。 1 size_t Queue::pop(int &value) 2 { 3 AutoLock lock(_poplock); 4 if (!empty()) { 5 value = _queue[_read]; 6 ++ _read; 7 if (_read == _maxsize) { 8 _read = 0; 9 } 10 return 1;11 }12 return 0;13 }14 15 size_t Queue::push(int value)16 {17 AutoLock lock(_pushlock);18 if (!full()) {19 _queue[_write] = value;20 ++ _write;21 if (_write == _maxsize) {22 _write = 0

乐观锁与悲观锁

十年热恋 提交于 2020-03-14 04:40:25
何谓悲观锁与乐观锁 乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。 (1)悲观锁: 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中 synchronized 和 ReentrantLock 等独占锁就是悲观锁思想的实现。 (2)乐观锁: 总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中 java.util.concurrent.atomic 包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。 两种锁的使用场景 从上面对两种锁的介绍,我们知道两种锁各有优缺点,不可认为一种好于另一种,像乐观锁适用于写比较少的情况下(多读场景)

C# Socket连接超时设置

好久不见. 提交于 2020-03-14 04:22:19
问题描述: 对于C# Socket没有超时设置的选项,默认情况下进行Socket连接,返回连接失败需要20-30s时间,严重影响用户体验 问题解决: Socket服务器端: Socket客户端: IAsyncResult.AsyncState 返回一个对象,该对象时启动异步操作的方法的最后一个参数 注: 在Socket客户端进行超时连接的设置,异步连接,设置连接处理的回调函数,以及超时的处理。 ManualResetEvent的WaitOne(TimeSpan, Boolean)起到了主要的作用。它将阻止当前线程,直到ManualResetEvent对象被Set或者超过timeout时间。上面的代码中,调用BeginConnect后通过WaitOne方法阻止当前线程,如果在timeoutMSec时间内连接成功,将在CallBackMethod回调中调用TimeoutObject.Set,解除被阻塞的连接线程并返回;否则,连接线程会在等待超时后,主动关闭连接并抛出TimeoutException。 参考资料: http://www.cnblogs.com/weidagang2046/archive/2009/02/07/1385977.html http://www.codeproject.com/Articles/31514/Implementation-of-Connecting

JAVA多线程 - 对象锁

谁说胖子不能爱 提交于 2020-03-14 01:51:53
多线程并发,给我们编程带来很多好处,完成更多更有效率的程序。但是也给我们带来线程安全问题。比如多个线程同时操作一个对象时,第一个线程没处理好,第二个线程就进来插一脚,影响了程序执行。为了每个线程被安全执行,需要引入一个对象锁的概念,也就是线程同步方法。    synchronized(Objecrt){你要同步的代码} 实例 模拟一个机票系统:有三个售票点,一天共同卖出2000张票。 1 /* 2 * 作者:白客C 3 * 时间:2020年03月13日 4 * 内容:线程锁实例 5 */ 6 7 package com.beekc.www; 8 9 public class Beekc{ 10 11 public static void main(String[] args) 12 { 13 //定义三个售票窗口 14 TicketWindow ticketWindow1 = new TicketWindow(); 15 //TicketWindow ticketWindow2 = new TicketWindow(); 16 //TicketWindow ticketWindow3 = new TicketWindow(); 17 18 //启动线程 19 Thread t1 = new Thread(ticketWindow1); 20 Thread t2 = new

创建型模式之单例模式

▼魔方 西西 提交于 2020-03-14 01:49:26
一、介绍 类的单例设计模式,就是采用一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。 二、单例模式八种方式 饿汉式(静态常量) 饿汉式(静态代码块) 懒汉式(线程不安全) 懒汉式(线程安全,同步方法) 懒汉式(线程安全,同步代码块) 双重检查 静态内部类 枚举 1、饿汉式(静态常量) class Singleton{ // 1.构造器私有化,外部不能new private Singleton(){} // 2.本类内部创建对象实例 private final static Singleton instance = new Singleton(); // 3.提供一个共有的静态方法,返回实例对象 public static Singleton getInstance(){ return instance; } } 优缺点: 优点:方法简单,在类装载的时候就完成实例化,避免线程同步。 缺点:没有达到 Lazy Loading 的效果。如果从始至终没有使用这个实例,则造成内存浪费。 结论:可用,但可能造成内存浪费。 2、饿汉式(静态代码块) class Singleton{ // 1.构造器私有化,外部不能new private Singleton(){} // 2.本类内部创建对象实例 private static

面试题目整理

安稳与你 提交于 2020-03-13 18:45:43
HTML&CSS 1、常用哪几种浏览器测试?有哪些内核(Layout Engine)? (Q1)浏览器:IE,Chrome,Firefox,Safari,Opera (Q2)内核:Trident,Gecko,Presto,Webkit 2、说下行内元素和块级元素的区别?行内块元素的兼容性使用?(IE8以下) (Q1)行内元素:会在水平方向排列,不能包含块级元素,设置width无效,height无效(可以设置line-height),margin上下无效 padding上下无效。块级元素:各占据一行,垂直方向排列。从新行开始结束接着一个断行 (Q2)兼容性:display:inline-block;*display:inline;*zoom:1; 3、清除浮动有哪些方式?比较好的方式是哪一种 (Q1)(1)父级div定义height (2)结尾处加空div标签clear:both (3)父级div定义伪类:after和zoom (4)父级div定义overflow:hidden (5)父级div定义overflow:auto (6)父级div也浮动,需要定义宽度 (7)父级div定义display:table (8)结尾处加br标签clear:both (Q2)比较好的是第3种方式,好多网站都这么用 1、box-sizing 常用的属性有哪些?分别有什么作用? (Q1)box

多线程笔试面试概念问答

我的未来我决定 提交于 2020-03-13 17:30:45
题目转自http://blog.csdn.net/morewindows/article/details/7392749 第一题:线程的基本概念、线程的基本状态及状态之间的关系? 线程,有时称为轻量级进程,是CPU使用的基本单元;它由线程ID、程序计数器、寄存器集合和堆栈组成。它与属于同一进程的其他线程共享其代码段、数据段和其他操作系统资源(如打开文件和信号)。 线程有四种状态:新生状态、可运行状态、被阻塞状态、死亡状态。状态之间的转换如下图所示: 第二题:线程与进程的区别? 1、 线程是进程的一部分,所以线程有的时候被称为是轻权进程或者轻量级进程。 2、 一个没有线程的进程是可以被看作单线程的,如果一个进程内拥有多个进程,进程的执行过程不是一条线(线程)的,而是多条线(线程)共同完成的。 3、 系统在运行的时候会为每个进程分配不同的内存区域,但是不会为线程分配内存(线程所使用的资源是它所属的进程的资源),线程组只能共享资源。那就是说,出了CPU之外(线程在运行的时候要占用CPU资源),计算机内部的软硬件资源的分配与线程无关,线程只能共享它所属进程的资源。 4、 与进程的控制表PCB相似,线程也有自己的控制表TCB,但是TCB中所保存的线程状态比PCB表中少多了。 5、 进程是系统所有资源分配时候的一个基本单位,拥有一个完整的虚拟空间地址,并不依赖线程而独立存在。 第三题

Android性能优化--Listview优化

删除回忆录丶 提交于 2020-03-13 15:04:38
ListView 的工作原理 首先来了解一下ListView的工作原理(可参见http://mobile.51cto.com/abased-410889.htm),如图: ListView 针对每个item,要求 adapter “返回一个视图” (getView),也就是说ListView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到ListView的长度,然后根据这个长度,调用getView()一行一行的绘制ListView的每一项。如果你的getCount()返回值是0的话,列表一行都不会显示,如果返回1,就只显示一行。返回几则显示几行。如果我们有几千几万甚至更多的item要显示怎么办?为每个Item创建一个新的View?不可能!!!实际上Android早已经缓存了这些视图,大家可以看下下面这个截图来理解下,这个图是解释ListView工作原理的最经典的图了大家可以收藏下,不懂的时候拿来看看,加深理解,其实Android中有个叫做Recycler的构件,顺带列举下与Recycler相关的已经由Google做过N多优化过的东东比如:AbsListView.RecyclerListener、ViewDebug.RecyclerTraceType等等,要了解的朋友自己查下,不难理解,下图是ListView加载数据的工作原理(原理图看不清楚的点击后看大图)

JVM学习(4):垃圾回收

余生颓废 提交于 2020-03-13 13:18:27
进行垃圾回收的区域 :堆,方法区 运行时数据区的【堆】和【方法区】在所有线程间是共享的,进行回收 【栈】是线程私有的,所有不进行回收 什么情况下进行回收: 开发中经常有这样的写法 List<String> list = new ArrayList<>(); list.add(); list.add(); list.add(); //业务逻辑代码 return ; 这样是不合理的,list是一个局部变量,使用完毕之后应该赋值为null 这段代码,然后使用参数-XX:+PrintGCDetails -XX:+UseSerialGC public class ReferenceCountingGC { private static final int MB = 1024 * 1024; Object instance = null; private byte[] size = new byte[2 * MB]; public static void main(String[] args) { ReferenceCountingGC o1 = new ReferenceCountingGC(); ReferenceCountingGC o2 = new ReferenceCountingGC(); o1.instance = o2; o2.instance = o1; o1 = null;