并发编程的目的是为了让程序运行的更快,但是并不是启动更多的线程就能让程序最大限度的并发执行。线程是java语言中重要的功能,它简化了复杂系统的开发。线程也被称为轻量级进程,在大多数现代操作系统中,都是以线程为基本调度单位的,而不是进程。
并发的简史:在早期的计算机中不包含操作系统,它们从头到尾只执行一个程序,并且这个程序可以访问计算机中的所有资源。这样不仅难以编写和运行程序,而且造成资源的极大浪费。操作系统的出现使得计算机可以每次运行多个程序,并且不同的程序都在单独的进程中运行:操作系统为每个独立的进程分配各种资源,包括内存,文件句柄以及安全证书等。如果需要的话,在不同的进程间可以通过一些粗粒度的通信机制来交换数据,包括:套接字,信号处理器,共享内存,信号量以及文件等。
使用线程有什么优势呢?1.发挥多处理器的强大能力。2.建模的简单性。3.异步事件的简化处理。4.响应更灵敏的用户界面。当然线程也有风险,都有什么风险呢?1.安全性问题(非常复杂的问题) 2.活跃性问题。3.性能问题。在多线程的程序中当线程调度器临时挂起活跃线程并转而运行另一个线程,就会频繁的出现上下文切换操作,这种操作将会带来极大的开销。
什么是上下文切换呢?CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是在切换前会保存上一个任务的状态,以便下次切换回这个任务时可以再加载这个任务的状态。所以任务从保存到再夹杂物i的过程就是一次上下文的切换。但是使用多线程一定快吗?下面的程序验证一下:
package chapterOne;
/**
* @author acer
* 对比串行与并发消耗的时间
*/
public class ConcurrencyTest {
private static final long count = l;
public static void main(String[] args) {
try {
concurrency();
} catch (InterruptedException e) {
e.printStackTrace();
}
serial();
}
/**
* 使用并发执行
* @throws InterruptedException
*/
public static void concurrency() throws InterruptedException{
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable(){
@Override
public void run() {
int a = ;
for(long i=;i<count;i++) {
a += ;
}
}
});
thread.start();
int b = ;
for(long i=;i<count;i++) {
b--;
}
thread.join();
long time = System.currentTimeMillis()-start;
System.out.println("concurrency:"+time);
}
public static void serial(){
long start = System.currentTimeMillis();
int a = ;
for(long i=;i<count;i++) {
a += ;
}
int b = ;
for(long i=;i<count;i++) {
b--;
}
long time = System.currentTimeMillis();
System.out.println("serial:"+time);
}
}
运行结果是串行0 并发1.可以并不是并发就一定快。这是因为有线程的创建以及上下文切换的开销。ime);
“`
运行结果是串行0 并发1.可以并不是并发就一定快。这是因为有线程。
何减少上下文的切换呢?常用的方法有一下几种。1.无锁并发编程 2.CAS算法 3.使用最少线程和使用协程。第一次使用这个编辑器,有点不大熟,这篇博客下文接着。