专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 移动开发

Java多线程高并发基础篇(4)-线程的上下文切换

发布时间:2010-05-29 22:00:11 文章来源:www.iduyao.cn 采编人员:星星草
Java多线程高并发基础篇(四)-线程的上下文切换

对于后端开发来说,上下文我们常接触.

那什么是线程的上下文切换?

1.线程的上下文切换

       在基础篇(一)中,我们讲到了时间片的概念.在单核处理器中,CPU就是通过给每个线程分配时间片执行来实现多线程.时间片是CPU分配给每个线程的执行时间段,这段时间都很短,只有几毫秒(ms),所以CPU必须来回切换各个线程来执行各自的任务,这样,对外看来,是在同时执行多个任务.

可能让我们疑惑的是,CPU如何保证下次再执行某个线程时,能正确记住该线程执行任务的状态?这就是我们要说的线程的上下文切换.CPU通过时间片分配算法来实现多任务,当前任务执行完对应的时间片后,需要切换到下一个任务.但是,在切换到下一个任务之前,需要保存上一个任务的状态,以便下次切换到该任务时,能正确的加载该任务的状态.这个过程就叫做线程的上下文切换.

       举个例子,我记得上小学时候,老师讲课中间,其他老师会半途过来借东西,然后老师需要停下讲课内容,然后把东西借出去,然后说一句:我们继续.在这个过程中,老师必须要在脑子中记忆刚到的地方,不至于被其他事情打断后重来.这个过程就是上一件事情和下一件事情之间的切换.

       因为有其他任务/事情插入,所以我们正在做的任务/事情会被中断,影响效率.因此,多线程任务的上下文切换是会影响执行效率的.

 

2.多线程执行与串行执行效率比较

多线程执行一定快吗?答案是不一定.我们模拟下面的执行过程.

public class CurrentSpeedTestDemo {
	private static final long count = 10000l;
	public static void main(String[] args) throws InterruptedException {
		concurrencyCount();
		serialCount();
	}
	private static void concurrencyCount() throws InterruptedException {
		long start = System.currentTimeMillis();
		final 
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				int b = 0;
				for (long i = 0; i < count; i++) {
					b += 5;
				}
				System.out.println("并行执行得到:b=" + b);
			}
		});
		thread.start();
		long time = System.currentTimeMillis() - start;
		System.out.println("并行执行花费时间:" + time+"ms");
	}
	private static void serialCount() {
		long start = System.currentTimeMillis();
		int b = 0;
		for (long i = 0; i < count; i++) {
			b += 5;
		}
		long time = System.currentTimeMillis() - start;
		System.out.println("串行执行得到:b=" + b);
		System.out.println("串行执行花费时间:" + time+"ms");
	}
}

 

执行效果如下:(这是我的电脑执行效果)


 

从执行测试效果可以看出,当累加操作在1万次时,并行是慢于串行执行的.

 

3.减少上下文切换

减少上下文切换的方法有多种,常用的有 无锁并发编程,CAS,使用最少线程,使用协程.

①无锁并发编程:在编程中,首先考虑无锁实现.

②CAS:比较交换,在Java的原子类实现中,使用CAS来做数据更新.

③使用最少线程:在并发很小的情况下,尽量不使用大量线程.

④使用协程:协程可以实现在单线程的情况下多任务的切换.

 

 

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: