个人小笔记之-java Semaphore
来源:互联网 发布:知乎离职员工 编辑:程序博客网 时间:2024/06/07 05:44
今天在仿照慕课网上自己写一个Android的imgeLoader的时候用到了信号量Semaphore,其实这也是线程安全的一种实现方式,以前在学校操作系统的时候,关于读写操作这一块也是用到了信号量,今天在这里也将这个信号量给总结一下,首先先贴一下今天大致写的代码 。其中有信号量的使用
package FileUtils;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Looper;import android.os.Message;import android.util.DisplayMetrics;import android.util.Log;import android.view.ViewGroup;import android.widget.ImageView;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.lang.reflect.Field;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.LinkedList;import java.util.concurrent.Executor;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Semaphore;/** * Created by Administrator on 2017/4/10. */public class ImageLoader implements FileLoader<Bitmap> { /** * 队列的调度方式 * * @author zhy * */ public enum Type { FIFO, LIFO } //图片的缓存机制 ImageCache localImageCache = new ImageMemoryCache(); ImageCache URLImageCache = new ImageDoubleCache(); /** * 队列的调度方式 */ private Type mType = Type.LIFO; /** * 任务队列 */ private LinkedList<Runnable> mTasks; /** * 轮询的线程 */ private Thread mPoolThread; private Handler mPoolThreadHander; //下载线程池线程池,线程池数量为cpu数量 //加载线程池,默认大小为1 ExecutorService mThreadPool; private int ThreadCount = 1; //运行在UI线程的Handler用于给ImgeView设置图片 Handler mHandler; //引入一个1的信号量,确保mPoolThreadHander不为空 private volatile Semaphore mSemaphore = new Semaphore(0); //引入一个信号量,防止加入任务速度过快 private volatile Semaphore mPoolSemaphore; private static ImageLoader instance; public static ImageLoader getInstance(){ if(instance==null){ synchronized (ImageLoader.class){ if(instance==null){ instance = new ImageLoader(1, Type.LIFO); } } } return instance; } @Override public Bitmap getFile(String url) { return null; } private ImageLoader(int threadCount,Type type){ init(threadCount,type); } private void init(int threadCount, Type type) { //初始化变量 mThreadPool = Executors.newFixedThreadPool(threadCount); mPoolSemaphore = new Semaphore(threadCount); mTasks = new LinkedList<Runnable>(); mType = type == null ? Type.LIFO : type; //开启轮训线程 mPoolThread = new Thread(new Runnable() { @Override public void run() { // 初始化轮询消息队列 Looper.prepare(); mPoolThreadHander = new Handler(){ @Override public void handleMessage(Message msg) { //取出任务,并且进行执行 mThreadPool.execute(getTask()); //信号量阻塞 try { mPoolSemaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } } }; //handler初始化完成后,释放信号量,这时候才能添加任务 mSemaphore.release(); //开始消息队列循环 Looper.loop(); } }); //开启轮询线程 mPoolThread.start(); } //取出轮序线程中的任务 private synchronized Runnable getTask(){ //判断轮序的顺序 if(mType==Type.FIFO){ return mTasks.removeFirst(); } if(mType==Type.LIFO){ return mTasks.removeLast(); } return null; } //添加任务到轮询线程 private synchronized void addTask(Runnable task){ if( mPoolThreadHander==null) { try { mSemaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } } mTasks.add(task); mPoolThreadHander.sendEmptyMessage(0x110); } public void loadImage(final String path, final ImageView imgeView, boolean isFromLocal){ imgeView.setTag(path); mHandler =new Handler(){ @Override public void handleMessage(Message msg) { ImageHolder holder = (ImageHolder) msg.obj; String path = holder.key; Bitmap bitmap =holder.bitmap; if(path.equals(imgeView.getTag().toString())){ imgeView.setImageBitmap(bitmap); } } }; //判断图片加载方式 if(isFromLocal){ Bitmap bitmap= localImageCache.get(path); if(bitmap!=null){ ImageHolder holder = new ImageHolder(); holder.key=path; holder.bitmap =bitmap; Message message = new Message(); message.obj =holder; mHandler.sendMessage(message); }else{ addTask(new Runnable() { @Override public void run() { //根据path从内存中获取,并且进行压缩发,handler发送 Bitmap bitmap = BitmapFactory.decodeFile(path); //进行压缩 ImageSize imageSize = getImageViewSize(imgeView); bitmap = decodeSampledBitmapFromResource(bitmap,imageSize.width,imageSize.height); ImageHolder holder = new ImageHolder(); holder.key=path; holder.bitmap =bitmap; Message message = new Message(); message.obj =holder; mHandler.sendMessage(message); mPoolSemaphore.release(); } }); } }else { //从网络的加载方式 Bitmap bitmap = URLImageCache.get(path); if (bitmap != null) { ImageHolder holder = new ImageHolder(); holder.key = path; holder.bitmap = bitmap; Message message = new Message(); message.obj = holder; mHandler.sendMessage(message); } else { addTask(new Runnable() { @Override public void run() { //根据path从网络中获取中获取,并且进行压缩发,handler发送 Bitmap bitmap = BitmapFactory.decodeFile(path); //进行压缩 ImageSize imageSize = getImageViewSize(imgeView); bitmap = decodeSampledBitmapFromResource(bitmap, imageSize.width, imageSize.height); ImageHolder holder = new ImageHolder(); holder.key = path; holder.bitmap = bitmap; Message message = new Message(); message.obj = holder; mHandler.sendMessage(message); mPoolSemaphore.release(); } }); } } } //图片显示 public void loadLocalImage(String path,ImageView imgeView){ loadImage(path,imgeView,true); } public void LoadURLImage(String path,ImageView imgeView){ loadImage(path,imgeView,false); } //图片的压缩处理 //根据imageView获取相应的宽高 private ImageSize getImageViewSize(ImageView imgeView){ ImageSize imageSize = new ImageSize(); //获取屏幕的宽和高 DisplayMetrics displayMetrics = imgeView.getResources().getDisplayMetrics(); ViewGroup.LayoutParams params = imgeView.getLayoutParams(); int width = params.width== ViewGroup.LayoutParams.WRAP_CONTENT?0:imgeView.getWidth(); int height = params.height== ViewGroup.LayoutParams.WRAP_CONTENT?0:imgeView.getHeight(); if(width<=0){ width =params.width; } if(width<=0){ width = getImageViewFieldValue(imgeView,"mMaxWidth"); }if(width<=0){ width = displayMetrics.widthPixels; } //高度 if( height<=0){ height =params. height; } if( height<=0){ height = getImageViewFieldValue(imgeView,"mMaxHeight"); }if(width<=0){ height = displayMetrics.heightPixels; } imageSize.height=height; imageSize.width = width; return imageSize; } /** * 反射获得ImageView设置的最大宽度和高度 * * @param object * @param fieldName * @return */ private static int getImageViewFieldValue(Object object, String fieldName) { int value = 0; try { Field field = ImageView.class.getDeclaredField(fieldName); field.setAccessible(true); int fieldValue = (Integer) field.get(object); if (fieldValue > 0 && fieldValue < Integer.MAX_VALUE) { value = fieldValue; Log.e("TAG", value + ""); } } catch (Exception e) { } return value; } // 计算insamplesize用于压缩图片 private int caculateInsampleSize(BitmapFactory.Options option,int reqWidth,int reqHeight){ int inSampleSize = 1; int width =option.outWidth; int height = option.outHeight; if(width>reqWidth&&height>reqHeight){ int widthRadius = Math.round((float) width / (float) reqWidth); int heightRadius = Math.round((float) height / (float) reqHeight); inSampleSize = Math.max(widthRadius,heightRadius); } return inSampleSize; } //根据计算的出的压缩比例 private Bitmap decodeSampledBitmapFromResource( Bitmap image, int reqWidth, int reqHeight) { ByteArrayOutputStream out = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG,100,out); // 第一次解析将inJustDecodeBounds设置为true,来获取图片大小 final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; // 调用上面定义的方法计算inSampleSize值 options.inSampleSize = caculateInsampleSize(options, reqWidth, reqHeight); // 使用获取到的inSampleSize值再次解析图片 options.inJustDecodeBounds = false; ByteArrayInputStream isBm = new ByteArrayInputStream(out.toByteArray()); Bitmap bitmap = BitmapFactory.decodeStream(isBm,null,options); return bitmap; } public void setURLImageCache(ImageCache imageCache){ this.URLImageCache = imageCache; } //UI线程的handler图片加载 //图片宽高 class ImageSize{ int width; int height; } //imageholder class ImageHolder{ String key; Bitmap bitmap; }}
Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做完自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞
acquire方法会申请信号量,但是当信号量已经达到阈值的时候,这时候线程就会再次堵塞,知道其他线程release后,自己抢占的信号量才会继续往下走,所以对于java多线程,信号量也是加锁的一种办法
0 0
- 个人小笔记之-java Semaphore
- Java多线程之Semaphore
- Java线程之Semaphore
- Java之Semaphore
- JAVA多线程之Semaphore
- java之Semaphore
- java线程之Semaphore
- Java多线程之Semaphore
- java之Semaphore
- Java多线程之Semaphore
- Java之Semaphore
- Java之Semaphore
- Java之Semaphore
- Java之Semaphore
- Java之Semaphore
- Java之Semaphore
- Java之Semaphore
- Java并发之Semaphore
- 第十一章 关联容器(重点)
- 多校联合集训 G. 数字逻辑练习题 (普通计算)
- TimePickerDialog时间选择器的使用,并设置时间格式
- Java集合概要
- 选择排序
- 个人小笔记之-java Semaphore
- java SSLContext
- 第一天先来认识认识namespace
- Elasticsearch5.0 安装问题集锦
- Salvation(dfs)
- 算法时间复杂度分析(1)
- 散列表的基本原理与实现
- Payment:支付的回调统一处理
- OJ编程题教训