现在web程序的计数器的应用场景比较多,分布式计数器可以使用redis,但是作为java程序员就会考虑怎么使用单节点多线程实现一个计数器。
计数器有两个层次的要求
1,多个线程访问不会造成计数器数值丢失
2,是否对计数器返回的值有要求,比如打印,比如用这个值做些事情
如果要满足2的话,那只有一种方式就是加锁,把相应的代码块加锁
如果要满足1的话,有两种思路,一个使用Java的并发包里面的atomic类型,一种是使用volatile变量然后使用sychronized变量。
因此有了如下两个程序
程序1
package com.fb.concurrency; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicInteger; public class MutiThreadCount implements Callable<Long> { private AtomicInteger ai = new AtomicInteger(); public MutiThreadCount() { } @Override public Long call() { Long start = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { ai.incrementAndGet(); } Long end = System.currentTimeMillis(); return end - start; } public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService es = Executors.newFixedThreadPool(1000); Long maxtime = 0l; MutiThreadCount mtc = new MutiThreadCount(); List<Future<Long>> result = new ArrayList<Future<Long>>(); for (int i = 0; i < 1000; i++) { Future<Long> time = es.submit(mtc); result.add(time); } es.shutdown(); for (Future<Long> f : result) { Long time = f.get(); if (time > maxtime) { maxtime = time; } } System.out.println(maxtime); System.out.println(mtc.ai.get()); } }
程序2:
package com.fb.concurrency; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class MutiThread1Count implements Callable<Long> { private int counting; @Override public Long call() { Long start = System.currentTimeMillis(); for (int i = 0; i < 100000; i++) { incr(); } Long end = System.currentTimeMillis(); return end - start; } public synchronized void incr() { counting++; } public static void main(String[] args) throws InterruptedException, ExecutionException { Long start = System.currentTimeMillis(); ExecutorService es = Executors.newFixedThreadPool(1000); MutiThread1Count mtc1 = new MutiThread1Count(); List<Future<Long>> result = new ArrayList<Future<Long>>(); for (int i = 0; i < 1000; i++) { Future<Long> time = es.submit(mtc1); result.add(time); } es.shutdown(); Long maxtime = 0l; Long total = 0l; for (Future<Long> f : result) { Long time = f.get(); if (time > maxtime) { maxtime = time; } total += time; } System.out.println("avg time is :" + total / result.size()); System.out.println(maxtime); System.out.println(mtc1.counting); Long end = System.currentTimeMillis(); System.out.println(end - start); } }
但是,在本机环境(intel I7 4核8线程)执行的时候,第一个程序可以吃到100%的cpu,第二个程序最多使用4个cpu线程,而且还不会到100%。
简单的理解就是:第一个程序不阻塞,全线程的跑,第二个线程synchronized会有可能导致每次都会重选进入锁的程序。
但是还是比较质疑这个想法:volatile变量使用比较脆弱,第二种调用效率按说应该比第一个高,参考:
www.ibm.com/developerworks/cn/java/j-jtp06197.html
为什么呢?
相关推荐
Java多线程代码行数计数器是一款实用的工具,主要功能是针对特定后缀名的文件进行代码行数的统计。在软件工程中,了解代码行数有时可以帮助开发者评估项目规模,跟踪代码增长,或者在性能优化时作为参考。这款工具...
JAVA多线程练习题答案详解 在本文中,我们将对 JAVA 多线程练习题的答案进行详细的解释和分析。这些题目涵盖了 JAVA 多线程编程的基本概念和技术,包括线程的生命周期、线程同步、线程状态、线程优先级、线程安全等...
在Java编程中,多线程并发是提升程序执行效率、充分利用多核处理器资源的重要手段。本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是...
《Java多线程编程实战指南-核心篇》是一本深入探讨Java并发编程的书籍,旨在帮助读者掌握在Java环境中创建、管理和同步线程的核心技术。Java的多线程能力是其强大之处,使得开发者能够在同一时间执行多个任务,提高...
Java多线程下载器是一种利用Java编程语言实现的高效文件下载工具,它通过将大文件分割成多个部分并同时下载,显著提高了下载速度。在Java中实现多线程下载器涉及许多关键概念和技术,包括线程、并发控制、网络I/O...
Java多线程设计模式是Java开发中的重要领域,它涉及到如何在并发环境下高效、安全地管理资源和控制程序执行流程。本资料集包含了清晰完整的PDF版书籍和源代码,为学习和理解Java多线程设计模式提供了丰富的素材。 ...
在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应...文档“java多线程实例.docx”可能包含具体的示例代码和详细解释,建议参考学习,以加深对Java多线程的理解。
Java多线程端口扫描是网络管理与安全领域中常用的一种技术,主要用于检测网络设备上哪些端口处于开放状态,从而分析网络的安全性或者优化网络配置。本程序通过利用Java的多线程特性,提高了扫描速度,使得在短时间内...
### Java多线程知识点详解 #### 一、Java多线程概述 **Java多线程**是指在Java程序中能够同时执行多个线程的技术。这种技术使得程序可以在多个任务之间并发执行,从而提高了程序的效率和资源利用率。本文将根据...
Java多线程设计模式是Java开发中的核心概念,它涉及到如何高效、安全地在多个执行线程之间共享资源和协调任务。设计模式是解决特定问题的成熟方案,它们是编程经验的结晶,可以帮助开发者在面临多线程挑战时快速找到...
Java多线程是Java编程语言中的一个重要特性,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在现代计算机系统中,多核处理器的普及使得多线程技术成为提升性能的关键手段。本篇将深入探讨Java多线程...
本示例“Android多线程实现简单字符串计数器”旨在教你如何在Android环境中利用多线程来实现一个简单的字符串计数器功能。 首先,我们需要理解Android中的线程模型。主线程,也称为UI线程,负责处理用户界面的更新...
通过这些实例,学习者能够深入理解Java多线程编程,提高解决实际并发问题的能力。每个章节的源码都是一个独立的案例,可以逐一研究,实践和调试,以便更好地掌握Java多线程编程技巧。在学习过程中,结合理论知识与...
Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了软件的效率和响应性。在Java中,多线程的实现主要有两种方式:通过继承Thread类和实现Runnable接口。这篇资料深入探讨了Java多线程的相关知识...
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的并发性和效率。在Java中,线程是程序执行的基本单元,是轻量级的进程,它们共享同一份代码和数据空间,但每个线程有自己的栈和程序...
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应性。在Java中,实现多线程有两种主要方式:通过实现`Runnable`接口或者继承`Thread`类。 首先,让我们从创建线程开始。当你...
在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了效率。本实例将探讨如何利用Java实现一个具有进度条显示功能的多线程应用。进度条通常用于可视化地表示某个任务的完成程度,这对于长...
本篇文章将深入探讨Java多线程下变量共享的问题以及解决策略。 在Java中,线程共享变量可以通过两种方式实现:静态成员变量和实例成员变量。静态成员属于类,所有该类的实例都可以访问,因此在多线程环境下默认共享...
最后,Java并发库还包含了很多其他有用的工具,如Semaphore(信号量)用于控制同时访问特定资源的线程数量,CyclicBarrier(循环屏障)和CountDownLatch(计数器门锁)用于多线程间的协作,以及Lock接口及其实现如...