java高并发点赞 java中高并发怎么处理_java高并发点赞

黄  静

合肥科技研发中心

进程与线程的简介

(1) 进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,即进程空间或(虚空间)。

(2) 线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,没有自己独立的虚拟地址空间,与进程内的其他线程一起共享该进程的所有资源。

(3) 进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大的提高了程序的运行效率:

从执行角度来看,线程不能够独立执行,必须依存于进程,由进程提供多个线程执行。

从逻辑角度来看,多线程的意义在于一个进程中,有多个执行流程可以同时执行。

线程生命周期的简介

(1) 一个线程被创建之后,进入新建状态,JVM则给他分配内存空间,并进行初始化操作。

(2) 当线程对象调用了start()方法,该线程处于就绪状态(即可执行状态),JVM会为其创建方法调用栈和程序计数器,处于可执行状态下的线程随时可以被CPU调度执行。CPU执行该线程的时候,该线程进入执行状态。

(3) 执行过程中,该线程遇到wait()方法进入等待状态;当线程调用同步方法时,在没有获取到锁的情况下,进入阻塞状态。

(4) 进入等待状态或阻塞状态后,可通过notify()或者notifyAll()方法唤醒,重新获取对象锁之后再进入就绪状态,等待CPU调度进入执行状态。

(5) 当线程执行完或者return线程正常结束。如果运行时发生未经处理的异常,则线程因为异常而结束。

用流程图直观的描述如下:

java高并发点赞 java中高并发怎么处理_多线程java_02

Java线程风险

(1) 安全性问题:会存在如下安全问题:内存共享、指令重排序、并行运行、操作顺序不可预测、会在串行编程模型中引入非串行因素,产生奇怪的结果等。例如经典账户存取款案例,如下:

java高并发点赞 java中高并发怎么处理_线程安全_03

从运行结果来看,账户只有100,分别取钱2次,金额分别是80和90,最后账户的余额还是10,产生了线程不安全问题。

(2) 活跃性问题:在串行程序中,无意中发生的无限循环,使得程序不能按照设计的流程继续执行,无法执行后面的代码,或者由于资源竞争而导致的死锁等。例如,如果线程1在等待线程2释放其持有的资源,而线程2永远不释放该资源,那么A就会永久地等待下去。

(3) 性能问题:在多线程程序中,不仅存在单线程程序相同的性能问题,而且还存在由于使用线程而引入的其他性能问题。例如服务时间过长,响应不灵敏,吞吐率过低,资源消耗过高,或者可伸缩性较低等。

多线程高并发风险处理方案

(1) 修改线程模型:不在线程之间共享该状态变量。

(2) 同步机制:通过synchronize和Lock可以实现同步,即当某一线程修改或访问可变变量时加锁,独占对象,让其他线程进不来。但是该方法容易造成死锁,所以要设计合理的释放锁的机制。

(3) 使用线程池:重用存在的线程,减少对象创建消亡的开销,可有效的控制最大并发线程数,提高系统资源利用率。

(4) 使用线程安全类:例如HashTable、StringBuffer都是线程安全的。

(5) 设计线程安全类:越早设计线程安全类,后期花费的代价就越小。设计线程安全类时,一般有如下流程:

找出构成对象状态的所有变量;

找出约束状态变量的不变性条件;

建立对象状态的并发访问管理策略:java监听器模式或线程安全委托。

写在最后

多线程高并发需要良好的设计来提升线程的性能,但无论如何线程总会带来额外的开销,本文意在让大家对线程高并发有一个初步的认识,深入学习还需要不断积累。