`
jean7155
  • 浏览: 63080 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

关于ExecutorService的使用

阅读更多
ExecutorService: 线程池, 顾名思义是一个调度线程运行的管理池。 我预制了一个场景: 在界面上,有5个图片需要进行异步加载, 我们使用了一个线程池管理类 AsyncImageLoader来控制加载图片的线程个数,如果加载的图片原本已经存在,则从系统中调出已有图片进行加载; 如果图片是首次加载,则通过连接加载图片。

1. 需要加载5个图片的界面:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 
 	<TextView 
 	    android:text="图片区域开始" 
 	    android:id="@+id/textView2"
 		android:layout_width="wrap_content" 
 		android:layout_height="wrap_content">
 	</TextView>

 	<ImageView 
 	    android:id="@+id/imageView1"
 		android:layout_height="wrap_content" 
 		android:src="@drawable/ic_launcher"
 		android:layout_width="wrap_content">
 	</ImageView>
	
	<ImageView 
	    android:id="@+id/imageView2"
 		android:layout_height="wrap_content" 
 		android:src="@drawable/ic_launcher"
 		android:layout_width="wrap_content">
	</ImageView>

	<ImageView 
	    android:id="@+id/imageView3"
 		android:layout_height="wrap_content" 
 		android:src="@drawable/ic_launcher"
 		android:layout_width="wrap_content">
	</ImageView>

	<ImageView 
	    android:id="@+id/imageView4"
 		android:layout_height="wrap_content" 
 		android:src="@drawable/ic_launcher"
 		android:layout_width="wrap_content">
	</ImageView>

	<ImageView 
	    android:id="@+id/imageView5"
 		android:layout_height="wrap_content" 
 		android:src="@drawable/ic_launcher"
 		android:layout_width="wrap_content">
	</ImageView>
 	
 	<TextView 
 	    android:text="图片区域结束" 
 	    android:id="@+id/textView1"
 		android:layout_width="wrap_content" 
 		android:layout_height="wrap_content">
 	</TextView>
</LinearLayout>


2. AsyncImageLoader类
public class AsyncImageLoader {
	
	public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String,SoftReference<Drawable>>();

        // 线程池的数量设置:在次,设置同时运行3个线程。 
	private ExecutorService executorService = Executors.newFixedThreadPool(3);
	
	private final Handler handler = new Handler();
	
	public ExecutorService getExecutorService() {
		return executorService;
	}

	public void setExecutorService(ExecutorService executorService) {
		this.executorService = executorService;
	}

	public Drawable loadDrawable(final String imageUrl, final ImageCallback callback){
		// 如果缓存中已经加载过该图片,则调用缓存中的图片加载
		if(imageCache.containsKey(imageUrl)){
			SoftReference<Drawable> softReference = imageCache.get(imageUrl);
			
			if(softReference.get()!=null){
				return softReference.get();
			}
		}
		
                // 首次加载图片的方法,使用线程池调用加载图片的线程
		executorService.submit(new Runnable(){

			@Override
			public void run() {
			
				try {  
                    // 加载图片
                    final Drawable drawable = loadImageFromUrl(imageUrl);
                    // 将图片的加载路径保存到缓存中
                    imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
                    // 图片加载完成后, 在界面中显示被加载的图片
                    handler.post(new Runnable() {  
                        public void run() {  
                            callback.imageLoader(drawable);
                        }  
                    });  
                } catch (Exception e) {  
                    throw new RuntimeException(e);  
                }  
			}
			
		});
		
		
		return null;
	}
	
	protected Drawable loadImageFromUrl(String imageUrl){
		 try {  
            return Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png");  
     } catch (Exception e) {  
             throw new RuntimeException(e);  
     }  
		
	}
	public interface ImageCallback{
		public void imageLoader(Drawable imageDrawable);
	}

        // 关闭线程池	
	public void shutdownAndAwaitTermination(ExecutorService pool) {
                   // 关闭线程池,新的任务就不再运行
		   pool.shutdown(); // Disable new tasks from being submitted

		   try {
		     // Wait a while for existing tasks to terminate
                     // 设置一个等待时间,使原来已经存在的任务完成其工作
		     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                    
		    	 pool.shutdownNow(); // Cancel currently executing tasks
			       // Wait a while for tasks to respond to being cancelled
		    	 Log.i("test", "i am shutting down...");
			       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
			           System.err.println("Pool did not terminate"); 
		     }
		       
		     
		   }catch (InterruptedException ie) {
		     // (Re-)Cancel if current thread also interrupted
			   Log.e("test","something interrupted happend, and i am shutting down....");
		     pool.shutdownNow();
		     // Preserve interrupt status
		     Thread.currentThread().interrupt();
		  }
	 }
}


3. 对AsyncImageLoader的调用异步加载这5个图片
public class BatchDownloadActivity extends Activity {

       //需要加载的图片名称	
	private static final String fileRealName = "我的图片1.gif";
	private String url;
	private int id;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
	
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.batch_download);
		
		String fileName = fileRealName;
		String url = "";
		
		try {
			url = ToolsUtil.getIpAddress() + URLEncoder.encode(fileRealName,"UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
                // url: http://xx.xx.xx.xx:port/webapp/filename.gif
		
		Log.i("test","url=" + url);
		
                // 调用加载图片方法
		loadImage(url, R.id.imageView1);
		loadImage(url, R.id.imageView2);
		loadImage(url, R.id.imageView3);
		loadImage(url,R.id.imageView4);
		loadImage(url,R.id.imageView5);
		
                //加载完成后,关闭线程管理池
		loader.shutdownAndAwaitTermination(loader.getExecutorService());
	
	}
	
	private AsyncImageLoader loader = new AsyncImageLoader();

	private void loadImage(final String url, final int id) {
		
		Drawable cacheImage = loader.loadDrawable(url,new AsyncImageLoader.ImageCallback() {  
				@Override
					public void imageLoader(Drawable imageDrawable) {
						
					     ((ImageView) findViewById(id)).setImageDrawable(imageDrawable);
					     Log.i("test", "loading new pic");
					}  
        });  

		if (cacheImage != null) {  
			((ImageView) findViewById(id)).setImageDrawable(cacheImage);  
			Log.i("test", "loading existing pic");
		}  
		
	}

}
分享到:
评论

相关推荐

    在spring boot中使用java线程池ExecutorService的讲解

    在 Spring Boot 中使用 Java 线程池 ExecutorService 的讲解 Spring Boot 作为一个流行的 Java 框架,提供了许多便捷的功能来帮助开发者快速构建应用程序。其中之一就是使用 Java 线程池 ExecutorService 来管理...

    java ExecutorService使用方法详解

    下面将详细讲解`ExecutorService`的使用方法。 1. **线程池创建** `ExecutorService`的实例通常通过`Executors`工厂类来创建。在示例中,使用`Executors.newFixedThreadPool(int nThreads)`创建了一个固定大小的...

    ExecutorService的execute和submit方法

    在Java多线程编程中,`ExecutorService`是线程池的核心接口,它提供了一种管理线程的方式,包括创建线程、调度线程执行以及控制线程的生命周期。`ExecutorService`通过`execute()`和`submit()`这两个方法来提交任务...

    ExecutorService方法案例文件.zip

    ExecutorService方法案例文件.zip

    ExecutorService与CompletionService对比详解.docx

    首先,我们来看ExecutorService的使用。在示例中,创建了一个固定大小的线程池(newFixedThreadPool(4)),然后将四个任务A、B、C、D分别提交到线程池执行。这些任务被包装为Future对象并存储在一个列表中。在遍历...

    ExecutorService线程池

    综上所述,ExecutorService线程池是Java并发编程中的重要工具,通过合理使用,我们可以有效地管理线程资源,提高程序的并发能力和稳定性。在项目开发中,了解和掌握线程池的使用和配置,对于提升系统性能和可维护性...

    ExecutorService用法详解.doc

    接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。壹個 ExecutorService 实例因此特别像壹個线程池。事实上,在 java.util.concurrent 包中的 ExecutorService 的实现...

    Executor,Executors,ExecutorService比较.docx

    通常,我们不会直接使用`Executor`,而是使用它的子接口`ExecutorService`,因为`ExecutorService`提供了更多的功能,如任务的提交、管理和关闭线程池。 2. **Executors** `Executors`是`java.util.concurrent`包...

    ExecutorService.shutdown()应该是在线程执行完毕后,才会去关闭

    至于`Java_并发编程培训(阿里巴巴).ppt`这个文件,很可能是阿里巴巴内部关于Java并发编程的一份培训材料,涵盖了更广泛的并发编程概念和实践,包括线程池的使用、并发工具类、锁机制、原子性操作、并发集合等。...

    Java使用ExecutorService来停止线程服务

    Java 使用 ExecutorService 来停止线程服务 Java 中的 ExecutorService 是一个非常强大的线程池管理工具,它提供了多种方式来停止线程服务。今天,我们将详细介绍如何使用 ExecutorService 来停止线程服务。 首先...

    详解Java利用ExecutorService实现同步执行大量线程

    为了解决同步和性能的问题,我们使用ExecutorService创建了一个单线程的线程池(通过Executors.newSingleThreadExecutor())。这样,所有提交到线程池的任务都会按照提交的顺序在单个线程中依次执行,从而确保对临界...

    运用JAVA的concurrent.ExecutorService线程池实现socket的TCP和UDP连接JAVA语言

    运用JAVA的concurrent.ExecutorService线程池实现socket的TCP和UDP连接

    java线程池工具--ExecutorService,简单例子

    NULL 博文链接:https://x125858805.iteye.com/blog/2191873

    理解java多线程中ExecutorService使用

    下面将深入解析`ExecutorService`的使用及其相关接口和类。 1. **ExecutorService接口**: `ExecutorService`继承自`Executor`接口,扩展了更多的功能。它的主要方法包括: - `execute(Runnable task)`:用于执行...

    2_ExecutorService源码阅读1

    ExecutorService 是 Java 中用于管理和控制线程执行的核心接口,它是 java.util.concurrent 包的一部分。ExecutorService 扩展了 ...熟练掌握 ExecutorService 的使用能够帮助开发者编写出高效、可控的并发代码。

    Java 线程池ExecutorService详解及实例代码

    以下是一个简单的ExecutorService使用示例: ```java ExecutorService executor = Executors.newFixedThreadPool(5); for (int i = 1; i ; i++) { final int taskID = i; executor.execute(() -&gt; { for (int j =...

    multithread:使用 Java8 ExecutorService 的简单多线程示例

    下面将详细介绍如何使用 `ExecutorService` 实现简单的多线程示例。 1. **ExecutorService**:ExecutorService 是 Executor 接口的一个实现,提供了更强大的功能,如线程池管理和任务调度。通过它,你可以提交任务...

    详解JDK中ExecutorService与Callable和Future对线程的支持

    Java并发编程中的ExecutorService、Callable和Future ...在实际应用中,我们可以使用ExecutorService、Callable和Future来实现各种并发编程任务,如统计某个盘子的大小、统计多个盘子的总大小、实现高效的数据处理等。

    java并发编程:Executor、Executors、ExecutorService.docx

    使用Executor、Executors和ExecutorService进行并发编程,可以帮助我们更有效地利用系统资源,避免线程创建和销毁的开销,同时提供了一套统一的接口来管理和控制并发任务,提高了程序的健壮性和可维护性。...

    2011.08.30(2)——— java BlockingQueue ExecutorService

    在TestBlockingQueueAndExecutorService这个测试用例中,作者可能演示了如何创建一个ExecutorService实例,然后将Runnable或Callable任务提交给它执行,同时使用BlockingQueue作为线程间的通信工具。通过这种方式,...

Global site tag (gtag.js) - Google Analytics