1、什么是并发
已知:多个进程或线程同时(或者说在同一段时间内)访问同一资源会产生并发问题。
1.1并发程序:
并发程序设计(concurrent programming)是指由若干个可在同一时间段执行的程序模块组成程序的程序设计方法。这种可并发执行的程序模块称为进程。进程由数据和机器指令和堆栈组成。组成一个程序的多个进程可以同时在多台处理器上并行执行,也可以在一台处理器上夹插执行。采用并发程序设计可以使外围设备和处理器并行工作,缩短程序执行时间,提高计算机系统的效率。在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
1.2并发访问:
在关系数据库中,允许多个用户同时访问和更改共享数据的进程。SQL Server 使用锁定以允许多个用户同时访问和更改共享数据而彼此之间不发生冲突。
1.3并发与并行的区别
并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。倘若在计算机系统中有多个处理机,则这些可以并发执行的程序便可被分配到多个处理机上,实现并行执行,即利用每个处理机来处理一个可并发执行的程序,这样,多个程序便可以同时执行。
1.4程序并发的特点
(1)程序与计算不再一一对应,一个程序副本可以有多个计算
(2)并发程序之间有相互制约关系,直接制约体现为一个程序需要另一个程序的计算结果,间接制约体现为多个程序竞争某一资源,如处理机、缓冲区等。
(3)并发程序在执行中是走走停停,断续推进的。
1.5现实中的并发例子
银行两操作员同时操作同一账户就是典型的例子。比如A、B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户减去 50元,A先提交,B后提交。 最后实际账户余额为1000-50=950元,但本该为 1000+100-50=1050。
2、如何处理并发
(1)程序在操作数据库的时候使用事务处理
(2)使用Hibernate的锁机制 悲观锁
(3)程序中使用同步异步、锁、多线程开启线程处理
3、JDK处理并发机制
在JDK1.5之前程序员需要手动编写多线程程序处理并发,JDK1.5之后Sun就提供了concurrent的处理包来处理并发问题了。总的来说就是使用线程池、锁、队列等的处理机制来处理并发。
以下是几个concurrent的核心类:
Executor :具体Runnable任务的执行者。
ExecutorService :一个线程池管理者,其实现类有多种,能把Runnable,Callable提交到池中让其调度。
Semaphore :一个计数信号量
ReentrantLock :一个可重入的互斥锁定 Lock,功能类似synchronized,但要强大的多。
Future :是与Runnable,Callable进行交互的接口,比如一个线程执行结束后取返回的结果等等,还提供了cancel终止线程。
BlockingQueue :阻塞队列。
CompletionService : ExecutorService的扩展,可以获得线程执行结果的
CountDownLatch :一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
CyclicBarrier :一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点
Future :Future 表示异步计算的结果。
ScheduledExecutorService :一个 ExecutorService,可安排在给定的延迟后运行或定期执行的命令。
........................
4、并发线程池使用示例package com.boonya.concurrent;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 多线程线程池使用示例
* @author BOONYACHENGDU@GMAIL.COM
* 查看线程执行的过程,以及并发处理的流程
*/
public class ConcurrentThreadPool {
/**
* 执行方法doSomething
* @param id
*/
private static void doSomething(int id) {
System.out.println("start do " + id + " task …");
try {
Thread.sleep(1000 * 2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("start do " + id + " finished.");
}
/**
* 开启线程并发测试
* @param args
*/
public static void main(String[] args) {
//创建了一个线程池,里面有2个线程
ExecutorService executorService = Executors.newFixedThreadPool(2);
//通过submit()方法,提交一个Runnable的实例,这个实例将交由线程池中空闲的线程执行
executorService.submit(new Runnable() {
@Override
public void run() {
doSomething(1);
}
});
executorService.submit(new Runnable() {
@Override
public void run() {
doSomething(2);
}
});
executorService.submit(new Runnable() {
@Override
public void run() {
doSomething(3);
}
});
//结束主线程,因为main函数也是一个线程
//不必担心,线程池不会直接关闭的,只有当它执行完所有提交的任务后才会关闭。
//如果不写这行,在本例中,应用将不会停止,因为虽然main线程(就是运行main
//方法的线程,也叫主线程)退出了,但是线程池中依然有线程运行,因此应用(进程)不会退出。
executorService.shutdown();
System.out.println(">>main thread end.");
}
}
分享到:
相关推荐
JDK自带线程池分析 JDK 自带线程池是 Java 语言中用于管理和执行线程的工具,旨在提高多线程...通过本文的介绍,我们可以了解 JDK 自带线程池的组成、创建方法和优点,从而更好地使用线程池来开发高效的多线程程序。
综上所述,JDK concurrent是一个涵盖广泛的主题,包括但不限于理解Java并发API的使用、源码分析、并发设计模式、监控和调试工具的运用。通过深入研究这个主题,开发者可以构建出更加稳定、高效和可扩展的并发应用...
JDK 1.5引入的`java.util.concurrent`包极大地简化了并发编程,提供了高效、可控的线程池管理。熟练掌握这些工具,能帮助开发者编写出更加稳定、高效的多线程应用程序。通过深入学习和实践,可以更好地理解和利用...
NULL 博文链接:https://hany.iteye.com/blog/516597
使用jdk1.5 实现的线程池. 可以定制人物和其它特性. 下载后可以自己进行相关功能完善. 欢迎加QQ:934547801一起讨论
"JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用" JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用是Java多线程编程中的一种重要概念。随着多线程编程的普及,线程池的使用变得...
介绍一个通用多线程服务模块。是利用jdk线程池,多线程并行处理多任务,以提高执行效率。
JDK1.5中的线程池(ThreadPoolExecutor)使用简介
jdk自带的线程池可以通过Executors工厂类来创建,Executors工厂类提供了多种创建线程池的方法,下面我们来看下使用示例: 1. newFixedThreadPool(固定大小的线程池) 使用newFixedThreadPool方法可以创建一个固定...
JDK 1.5引入了java.util.concurrent包,其中包含了线程池的实现,使得并发编程更加便捷和高效。线程池的核心在于它的设计策略,包括核心线程数、最大线程数、线程存活时间、工作队列以及拒绝策略。 线程池的主要类...
JDK1.5的线程池讲解,示例代码,很精辟~
JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用简介
JDK线程池和Spring线程池的使用实例解析 JDK线程池和Spring线程池是两种常用的线程池实现,它们都提供了线程池的功能,但它们在使用和配置上有所不同。下面我们将详细介绍JDK线程池和Spring线程池的使用实例解析。 ...
JDK 1.5 引入了一系列重要的并发编程新特性,极大地改善了多线程环境下的程序设计。这些特性使得开发者能够编写更加高效、安全的并发应用程序。以下是对这些新特性的详细解释: 1. `TimeUnit`: `TimeUnit` 是一个...
在JDK 1.5版本之前,Java对线程池的支持非常有限,而在JDK 1.5之后,加入了java.util.concurrent包,其中包含了一系列关于线程池的接口和类,极大地丰富了线程池的应用场景和管理方式。 线程池的主要作用是限制系统...
首先,Java中的线程池设计始于JDK 5.0,主要通过`java.util.concurrent`包中的`Executor`接口实现。这个接口仅有一个`execute()`方法,用于提交执行任务。我们也将遵循这个设计,实现一个简单的线程池类`...
资源很不错
开始从原始二进制研究Concurrent包,以及其他并发相关的包,对于途中遇到的不明白的东西,也会作相应了解。 该项目的缘由是看CopyOnWriteArrayList二进制时,对Unsafe类一无所知,才有了好钻钻一番的冲动。 ...
如何启动:以win7系统为例,最好jdk8 1.打开cmd,cd到jdk的path,本机是:cd C:\Java\jdk6\bin ...java -cp D:\javaConcurrentAnimated.jar vgrazi.concurrent.samples.launcher.ConcurrentExampleLauncher
使用线程池时,需要根据实际应用场景选择合适的线程池类型,并合理配置线程池的大小,以达到最佳的并发性能和资源利用率。此外,还需要关注线程池的异常处理和任务超时策略,确保系统的健壮性和稳定性。