多线程高并发编程总结

多线程数据库

第一章编程

一。终止线程的三种方法:设计模式

1.使用退出标志,是县城正常退出,也就是当run方法完成后线程终止。数组

2.stop不推荐缓存

3.使用interrupt(打了一个中止标记,并非真的中止线程)。安全

1)interrupt+throw new interruptexception(推荐使用,catch块中还能够将异常向上抛,使线程中止的事件得以传播。)多线程

2) interrupt+return并发

 二。this.interrupted()和this.isInterrupted()框架

1)this.interrupted():测试当前线程是否已是中断状态,执行后具备将状态标志清除为false的功能。异步

2)测试线程Thread对象是否已是中断状态,但不清除状态标志。

 三。stop方法为何不用?

1)已经做废,由于若是强制让线程中止则有可能使一些清理性的工做得不到完成。

2)另一个状况就是对锁定的对象镜像了“解锁”,致使数据得不到同步的处理,出现数据不一致的问题。

 四。suspend与resume的缺点:

1)独占锁

2)不一样步

五。守护进程:保姆,提供便利服务,只要当前进程实例中存在任何一个非守护进程 没有结束,守护进程就在工做,只有当最后一个非守护进程结束时,守护进程才随着jvm一同结束工做。典型应用是GC

第二章

 

一。synchronized锁重入:

本身能够再次获取本身的内部锁,好比有一条线程得到了某个对象的锁,此时这个对象锁尚未释放,当其再次想要获取这个对象的锁的时候仍是能够得到的,若是不可锁重入的话,就会形成死锁。

二。出现异常,锁自动释放。

三。同步不具备继承性

四。在使用同步synchronized(this)代码块时须要注意的是,当一个线程访问object的一个synchronized同步代码块时,其余线程对同一个object中全部其余synchronized同步代码块的访问将被阻塞,这说明synchronized使用的“对象监视器”是一个。

五。能够将this做为对象监视器,也能够将任意对象做为对象监视器。

六。synchroniezd(this)和synchronized同步方法的对象监视器都是对象自己。

七。锁非this对象具备必定的优势:若是在一个类中有不少的synchronized方法,这时虽然能实现同步,但会受到阻塞,因此会影响运行效率;但若是使用同步代码块锁非this对象,则synchronized(非this)代码块中的程序与同步方法是异步的,不与其余锁this同步方法争抢this锁,则能够大大提升效率。

八。synchronized还能够用在static静态方法上,对类进行加锁。和对象锁是不同的锁。

九。同步synchronized(class)代码块的做用其实和synchronized static方法的做用同样。

十。因为JVM中Strring常量池缓存的缘由,在大多数的状况下,同步synchronized带麦克都不使用String做为锁对象,而改用其余,好比new Obj,但它不放入缓存池中。或者byte[] a=new byte[0];说明:零长度的byte数组对象建立起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操做码,而Object lock = new Object()则须要7行操做码。

十一,只要对象不变,即便对象的属性被改变,运行的结果仍是同步。

十二。volatile:强制从公共堆栈中取得变量值,而不是从线程私有数据栈汇总取得变量的值。不支持原子性。

第三章 线程通讯。

一。wait使线程中止运行,而notify使中止的线程继续运行。在调用wait以前,线程必须得到该对象的对象级别锁,即只能在同步方法或同步块中调用wait方法。在执行wait后,当前线程释放锁。若是调用wait时没有持有适当的锁,则抛出illegalMonitorStateException。notify调用没有持有适当的锁也会illegalMonitorStateException。

二。notify方法执行后并不当即释放锁,wait当即释放。若是发出notify操做时没有处于阻塞状态中的线程,那么该命令会被忽略。

三。 线程切换:

 

1)新建立一个新的线程对象后,再调用它的star()方法,系统会为此线程分配CPU资源,使其处于Runnable (可运行)状态,这是一个准备运行的阶段。若是线程抢占到CPU资源,此线程就处于Running(运行)状态。
2) Runnable状态和Running状态可相互切换,由于有可能线程运行一段时间后, 有其余高优先级的线程抢占了CPU资源,这时此线程就从Running状态变成Runnable状态。
线程进入Runnable状态大致分为以下5种状况:
调用sleep)方法后通过的时间超过了指定的休眠时间。 
线程调用的阻塞IO已经返回,阻塞方法执行完毕。

线程成功地得到了试图同步的监视器。

线程正在等待某个通知,其余线程发出了通知。
处于挂起状态的线程调用了resume恢复方法。
3) Blocked是阻塞的意思,例如遇到了一个IO操做,此时CPU处于空闲状态,可能会转而把CPU时间片分配给其余线程,这时也能够称为“暂停”状态。Blocked 状态结束后,
进人Runnable状态,等待系统从新分配资源。
出现阻塞的状况大致分为以下5种:

线程调用seep方法,主动放弃占用的处理器资源。

线程调用了阻塞式IO方法,在该方法返回前,该线程被阻塞。

线程试图得到一个同步监视器,但该同步监视器正被其余线程所持有。

线程等待某个通知。
程序调用了suspend 方法将该线程挂起。此方法容易致使死锁,尽可能避免使用该方法。

4) run(方法运行结束后进人销毁阶段,整个线程执行完毕。

   每一个锁对象都有两个队列,一个是就绪队列,一个阻塞队列。就绪队列存储了将要得到锁的线程,阻塞队列存储了被阻塞的线程。一个线程被唤醒后,才会进人就绪队列,等待CPU的调度;反之,一个线程被wait后,就会进人阻塞队列,等待下一次被唤醒。 

 四。

1.sleep方法不释放锁。notify必须执行完notify方法所在的同步synchronized代码块后才释放锁。

2.

1)执行完同步代码块就会释放对象的锁。

2)在执行同步代码块的过程当中,遇到异常而致使线程终止,锁也会被释放。

3)在执行同步代码块的过程当中,执行了锁所属对象的wait方法,这个过程会释放对象锁,而此线程对象会进入线程等待池中,等待被唤醒。

五。线程之间通讯方式之:管道 pipeStream 4个类:PipeInputStream PipedReader

六。方法join:等待线程对象销毁,具备使线程排队运行的做用。有些相似同步的运行效果。join与synchronized的区别:join内部使用wait进行等待,而synchronize使用的是对象监视器原理同步。

七。join(long)和wait(long)的区别:方法join(long)功能内部是使用wait(long)来实现的,因此join方法具备释放锁的特色。

 

八。threadLocal类:主要解决的问题是每一个线程绑定本身的值。每个线程有本身的私有数据。

       InheritableThreadLocal能够在子进程中取得父进程继承下来的值。

第四章 Lock

一。lock.lock待的线程持有了“对象监视器”,其余线程只有等待被释放时再次争抢。

二。借助condition对象能够实现多路通知的功能,也就是在一个lock对象里面能够建立多个condition(对象监视器)实例,线程对象能够注册在指定的condition中,从而有选择的进行线程通知,在调度上更灵活。在使用notify/notifyall方法进行通知时,被通知的线程时jvm随机选择的。但使用rerntrantlock结合Condition类是能够实现“选择性通知”。synchronized至关于整个lock对象只有一个单一的condition对象,全部的线程都注册在它一个对象上。

三。wait至关于condition的await。wait(long timeout)至关于await(long)。notify至关于condition的signal,notifyall至关于signalAll。

四。想要实现一对一通知,只需建立对于的condition便可。Lock lock=new ReentrantLock;Condiition condition=lock.newCondition;

五。公平锁和非公平锁,是否按照线程加锁的顺序。FIFO.建立锁的时候能够用构造方法传入。默认是非公平锁。

六。使用condition能够实现线程的按顺序执行。使用多个condition和一个变量,这个变量要一直改变使一个线程能够执行,其余线程等待。

七。读写锁ReentrantReadWriteLock,提升代码运行速度(在不须要操做实例变量的方法中)。读操做相关的锁,也称共享索女,写操做的锁,也称排它锁。也就是读读不互斥,读写互斥。写写互斥。即多个线程能够同时读取操做,可是同一时刻只容许一个Thread写入操做。

第六七章 单例模式与多线程

一。使用DCL 双检查锁机制来实现多线程环境中的延迟加载单例设计模式。

那么咱们为何要使用两个if判断这个对象当前是否是空的呢 ?由于当有多个线程同时要建立对象的时候,多个线程有可能都中止在第一个if判断的地方,等待锁的释放,而后多个线程就都建立了对象,这样就不是单例模式了,因此咱们要用两个if来进行这个对象是否存在的判断。

其余方式:使用静态内置类。使用静态代码块。使用枚举类:构造方法自动调用。

二。simpledateformat非线程安全。解决方法一:建立多个simpleDateFormat。二:threadLocal

Java并发编程的艺术:

一。synchronized和lock的区别和优点

缺乏了隐式获取释放锁的便捷性,可是却拥有了锁获取与释放的可操做性、可中断的获取锁以及超时获取锁等synchronized不具有的同步特性。

1)尝试非阻塞地获取锁

2)能被中断地获取锁

3)超时获取锁

二。abstractQueueSynchronizer队列同步器,是用来构建锁或其余同步组件的基础框架。(不一样类型的同步组件ReentrantLock、ReentrantReadWriteLock和CountDownLatch等)

三。concurrentHashMap:HashTable在竞争激烈的并发环境下表现出效率低下的缘由是全部访问HashTable的线程都必须竞争通一把锁,假若有多把锁,每一把锁用于锁容器其中一部分数据,那么当多线程访问容器里不一样数据段的数据时,线程间就不会存在锁竞争,从而能够有效提升并发访问下来,这就是concurrentHashMap的锁分段技术。首先将数据分红一段一段存储,而后每一段数据配一把锁当一个线程占用锁访问期中一个段数据时,其余段的数据也能被其余线程访问。

四。CountDownLatch()和CyclicBarrier

cyclicBarrier:让一组线程到达一个屏障时被阻塞,知道最后一个线程到达屏障时,屏障才会开门,全部被屏障链接的线程才会继续进行。

countDownLatch的计数器只能使用一次,而cyclicBarrier的计数器可使用reset方法重置。

CountDownLatch:主要是-1操做,能够用在一个线程的n个步骤,也能够是n个线程。

semaphone:能够用来作流量控制,特别是公共资源有限的场景。好比数据库链接。acquire获取、release归还。

线程间交换数据的Exchanger:用于线程间协做。线程间数据交换,它提供一个同步点,在这个同步点,两个线程能够交换彼此的数据。若是一个线程先执行exchanger方法,它会一直等待第二个线程也执行,当两个线程到达同步点时,这两个线程就能够交换数据,将本线程生产出来的数据传递给对方。

相关文章
相关标签/搜索