提高系统性能之多线程编程

多线程编程技术在实际编程应用中十分广泛,多线程技术的应用通过提高CPU的利用率来帮助系统提升性能,那么究竟多线程编程在什么情况下使用?怎样使用多线程呢?多线程的应用一定要适应特定的环境,线程开多了会大大增加Cpu的负担,而线程数目开少了又很难提高cpu的利用率,为此我们使用线程池来管理线程。线程池用来限制线程的数量,减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务,同时可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存使得服务器宕机。那究竟什么是多线程呢?举个形象的比喻,多线程好比人的大脑,人可以同时做好几件事情,比如我么可以一边看电视一边喝茶,而不应是非要在看完电视后才能喝茶或喝完茶后才能看电视,这就是多线程的生活中的体现。举个你更加熟悉的例子,如果你想下载三个电影,大多数人是同时选中三个电影进行下载,相信没有人会一部一部的挨个下载吧,此时我们会一边下载电影一边察看各个电影的下载进度直到所有的电影都下载完毕。当然,这三个进程下载电影的过程都会受到网络带宽的影响,这也是他们所要用到的共同资源。下面我们就来模拟同时下载三个电影的过程。

1.我们为每个电影都开启一个线程,这个线程的实现方式我选择的是集成Thread类,重写其run()方法的方式,代码如下:

package edu.review.download2;

import java.util.concurrent.ExecutorService;

public class DownloadFile extends Thread {
	/*****静态变量用来模拟各线程共享资源******/
	private static Object obj = new Object();
	private String fileName;
	private int fileNum = 0;

	@Override
	public void run() {
		System.out.println("正在下载" + fileName);
		while (fileNum < 100 ) {
			fileNum++;
			System.out.println("《" + fileName + "》" + "已下载:" + fileNum + "%");
			tempThread();
		}
		if (fileNum >= 100) {
			System.out.println("《" + fileName + "》" + "下载完成");
			stop();
			resumeByNotify();

		}
	}

	/*****唤醒一个wait状态的进程******/
	public void resumeByNotify() {
		System.out.println(fileName + "动作,---通知一个");
		synchronized (obj) {
			obj.notify();
		}
	}

	/******唤醒所有wait状态的进程*******/
	public void resumeByNotifyAll() {
		System.out.println(fileName + "动作---全通知");
		synchronized (obj) {
			obj.notifyAll();
		}
	}

	public DownloadFile(String fileName) {
		this.fileName = fileName;
	}

	/*****当下载到一半的时候阻塞进程*****/
	private void tempThread(){
		if(fileNum == 50){
			//obj="false";
			synchronized (obj) {
				try {
					System.out.println("《" + fileName
							+ "》的下载由于网络原因被阻塞,正在等待唤醒");
					obj.wait();
					//obj.notify();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

2.线程执行类TaskExecutor,代码如下:

package edu.review.download2;

import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;

public class TaskExecutor {
	public static void main(String[] args) {

		/**** 创建一个可重用固定线程数的线程池*******/
		ExecutorService pool = Executors.newCachedThreadPool();

		/****** 创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口********/
		DownloadFile t1 = new DownloadFile("汉武大帝");
		DownloadFile t2 = new DownloadFile("秦始皇传");
		DownloadFile t3 = new DownloadFile("阿甘正传");
		t1.setPriority(9);
		t2.setPriority(5);
		t3.setPriority(1);
		/********** 将线程放入池中进行执行*******/
		pool.execute(t1);
		pool.execute(t2);
		pool.execute(t3);

		/*****主线程睡眠5秒*******/
		try {
			Thread.sleep(1000 * 5);
		} catch (InterruptedException e) {
			System.out.println("Main Thread Interrupted");
		}

		System.out.println("Resume By Notify");
		t2.resumeByNotifyAll();

		// 关闭线程池
		pool.shutdown();

	}
}

上面代码的实现思路是以obj类模拟共享资源,每个电影下载到一半的时候调用obj的wait()方法阻塞该进程,然后通过其中一个进程的notifyAll()操作唤醒所有的线程,让他们重新竞争cpu的使用权,直到所有的电影下载完毕。在线程执行类中我们同时下载了三部电影,然后给每个电影的下载操作开启一个线程,并将其放入到线程池中。线程池执行池对池中的所有线程进行管理,在这里我使用的是newCachedThreadPool,它创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。下面是执行结果当各个电影下载到50%的时候阻塞该线程,然后其中的一个线程执行唤醒全部操作,最后所有线程重新进入执行状态完成操作(由于数据量较大只能部分截图):

通过对比输出结果我们可以发现与我们之前分析的结果一样,这就是多线程实现多文件下载的实例,希望对于大家有所帮助。

时间: 2024-09-29 09:33:01

提高系统性能之多线程编程的相关文章

Swing多线程编程(转)

关键字: Swing,多线程,GUI,SwingWorker 摘要: 本文论述了怎样开发多线程的Swing程序,从而提高Swing程序的响应速度和性能. 近期,我将推出一系列研究Swing程序的文章,这也算是为了向Swing这个优秀的GUI库的设计者致敬吧! Swing这种优秀的GUI库一直不能占领桌面市场,实在令人费解,今天,我就用我的努力,为java在桌面市场的成功尽我微薄之力吧! Swing的单线程开发机制 多线程开发,显然要比单线程开发有趣.高效.美妙得多.特别是在Java这种天生支持多

5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq

在上一篇博客5天玩转C#并行和多线程编程 —— 第一天 认识Parallel中,我们学习了Parallel的用法.并行编程,本质上是多线程的编程,那么当多个线程同时处理一个任务的时候,必然会出现资源访问问题,及所谓的线程安全.就像现实中,我们开发项目,就是一个并行的例子,把不同的模块分给不同的人,同时进行,才能在短的时间内做出大的项目.如果大家都只管自己写自己的代码,写完后发现合并不到一起,那么这种并行就没有了意义. 并行算法的出现,随之而产生的也就有了并行集合,及线程安全集合:微软向的也算周到

C#并行和多线程编程

5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编程 —— 第三天 认识和使用Task 5天玩转C#并行和多线程编程 —— 第四天 Task进阶 5天玩转C#并行和多线程编程 —— 第五天 多线程编程大总结 在上一篇博客5天玩转C#并行和多线程编程 —— 第一天 认识Parallel

Hibernate 利用缓存(一级、二级、查询)提高系统性能

在hibernate中我们最常用的有三类缓存,分别为一级缓存.二级缓存和查询缓存,下面我们对这三个缓存在项目中的使用以及优缺点分析一下. 缓存它的作用在于提高性能系统性能,介于应用系统与数据库之间而存在于内存或磁盘上的数据. 首先,来看一下一级缓存它默认开启且很常用. 一级缓存 同是一种缓存常常可以有好几个名字,这是从不同的角度考虑的结果,从缓存的生命周期角度来看一级缓存又可以叫做:sessin缓存.线程级缓存.事务级缓存.我们编程中线程.事务.session这三个概念是绑定到一起的放到了thr

多线程编程简介

http://fanqiang.chinaunix.net/a4/b8/20010811/0905001105.html 1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix 也支持线程的概念,但是在一个进程(process)中只允许有一个线程,这样多线程就意味着多进程.现在,多线程技术已经被许多操作系统所支持,包括 Windows/NT,当然,也包括Linux. 为什么有了进程的概念后,还要再引

Java基础知识—多线程编程(五)

概述 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径.使用多线程也是为了充分的利用服务器资源,提高工作效率. 线程生命周期 线程是一个动态执行的过程,它也有一个从产生到死亡的过程. 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态.它保持这个状态直到程序 start() 这个线程. 就绪状态: 当线程对象调用了start()方法之后,该

多线程编程基础知识

多线程编程基础知识 http://www.cnblogs.com/cy163/archive/2006/11/02/547428.html 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.因此掌握

iOS多线程编程

1. 进程,线程, 任务 进程:一个程序在运行时,系统会为其分配一个进程,用以管理他的一些资源. 线程:进程内所包含的一个或多个执行单元称为线程,线程一般情况下不持有资源,但可以使用其所在进程的资源. 任务:进程或线程中要做的事情. 在引入线程的操作系统中,通常把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位. 线程比进程更小,对其调度的开销小,能够提高系统内多个任务的并发执行程度. 一个程序至少有一个进程,一个进程至少有一个线程.一个程序就是一个进程,而一个程序中的多个任

Java多线程编程模式实战指南(二):Immutable Object模式--转载

本文由本人首次发布在infoq中文站上:http://www.infoq.com/cn/articles/java-multithreaded-programming-mode-immutable-object.转载请注明作者: 黄文海 出处:http://viscent.iteye.com. 多线程共享变量的情况下,为了保证数据一致性,往往需要对这些变量的访问进行加锁.而锁本身又会带来一些问题和开销.Immutable Object模式使得我们可以在不使用锁的情况下,既保证共享变量访问的线程安