Java AtomicInteger类的使用方法详解
首先看两段代码,一段是integer的,一段是atomicinteger的,为以下:
public class sample1 { private static integer count = 0; synchronized public static void increment() { count++; } }
以下是atomicinteger的:
public class sample2 { private static atomicinteger count = new atomicinteger(0); public static void increment() { count.getandincrement(); } }
以上两段代码,在使用integer的时候,必须加上synchronized保证不会出现并发线程同时访问的情况,而在atomicinteger中却不用加上synchronized,在这里atomicinteger是提供原子操作的,下面就对这进行相应的介绍。
atomicinteger介绍
atomicinteger是一个提供原子操作的integer类,通过线程安全的方式操作加减。
atomicinteger使用场景
atomicinteger提供原子操作来进行integer的使用,因此十分适合高并发情况下的使用。
atomicinteger源码部分讲解
public class atomicinteger extends number implements java.io.serializable { private static final long serialversionuid = 6214790243416807050l; // setup to use unsafe.compareandswapint for updates private static final unsafe unsafe = unsafe.getunsafe(); private static final long valueoffset; static { try { valueoffset = unsafe.objectfieldoffset (atomicinteger.class.getdeclaredfield("value")); } catch (exception ex) { throw new error(ex); } } private volatile int value;
以上为atomicinteger中的部分源码,在这里说下其中的value,这里value使用了volatile关键字,volatile在这里可以做到的作用是使得多个线程可以共享变量,但是问题在于使用volatile将使得vm优化失去作用,导致效率较低,所以要在必要的时候使用,因此atomicinteger类不要随意使用,要在使用场景下使用。
atomicinteger实例使用
以下就是在多线程情况下,使用atomicinteger的一个实例,这段代码是借用it宅中的一段代码。
public class atomictest { static long randomtime() { return (long) (math.random() * 1000); } public static void main(string[] args) { // 阻塞队列,能容纳100个文件 final blockingqueue<file> queue = new linkedblockingqueue<file>(100); // 线程池 final executorservice exec = executors.newfixedthreadpool(5); final file root = new file("d:\\iso"); // 完成标志 final file exitfile = new file(""); // 原子整型,读个数 // atomicinteger可以在并发情况下达到原子化更新,避免使用了synchronized,而且性能非常高。 final atomicinteger rc = new atomicinteger(); // 原子整型,写个数 final atomicinteger wc = new atomicinteger(); // 读线程 runnable read = new runnable() { public void run() { scanfile(root); scanfile(exitfile); } public void scanfile(file file) { if (file.isdirectory()) { file[] files = file.listfiles(new filefilter() { public boolean accept(file pathname) { return pathname.isdirectory() || pathname.getpath().endswith(".iso"); } }); for (file one : files) scanfile(one); } else { try { // 原子整型的incrementandget方法,以原子方式将当前值加 1,返回更新的值 int index = rc.incrementandget(); system.out.println("read0: " + index + " " + file.getpath()); // 添加到阻塞队列中 queue.put(file); } catch (interruptedexception e) { } } } }; // submit方法提交一个 runnable 任务用于执行,并返回一个表示该任务的 future。 exec.submit(read); // 四个写线程 for (int index = 0; index < 4; index++) { // write thread final int num = index; runnable write = new runnable() { string threadname = "write" + num; public void run() { while (true) { try { thread.sleep(randomtime()); // 原子整型的incrementandget方法,以原子方式将当前值加 1,返回更新的值 int index = wc.incrementandget(); // 获取并移除此队列的头部,在元素变得可用之前一直等待(如果有必要)。 file file = queue.take(); // 队列已经无对象 if (file == exitfile) { // 再次添加"标志",以让其他线程正常退出 queue.put(exitfile); break; } system.out.println(threadname + ": " + index + " " + file.getpath()); } catch (interruptedexception e) { } } } }; exec.submit(write); } exec.shutdown(); } }
atomicinteger使用总结
atomicinteger是在使用非阻塞算法实现并发控制,在一些高并发程序中非常适合,但并不能每一种场景都适合,不同场景要使用使用不同的数值类。
以上就是本文关于java atomicinteger类的使用方法详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:java原生序列化和kryo序列化性能实例对比分析 、关于java企业级项目开发思想 、java map存放数组并取出值代码详解 等,有什么问题可以随时留言,小编会及时回复大家。