`
gaddma
  • 浏览: 17369 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JAVA多线程计数器的问题

 
阅读更多

现在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环境中创建、管理和同步线程的核心技术。Java的多线程能力是其强大之处,使得开发者能够在同一时间执行多个任务,提高...

    Java多线程下载器

    Java多线程下载器是一种利用Java编程语言实现的高效文件下载工具,它通过将大文件分割成多个部分并同时下载,显著提高了下载速度。在Java中实现多线程下载器涉及许多关键概念和技术,包括线程、并发控制、网络I/O...

    Java多线程设计模式_清晰完整PDF版 Java多线程设计模式源代码

    Java多线程设计模式是Java开发中的重要领域,它涉及到如何在并发环境下高效、安全地管理资源和控制程序执行流程。本资料集包含了清晰完整的PDF版书籍和源代码,为学习和理解Java多线程设计模式提供了丰富的素材。 ...

    java多线程示例

    在Java编程语言中,多线程是核心特性之一,它允许程序同时执行多个任务,从而提高了应用程序的效率和响应...文档“java多线程实例.docx”可能包含具体的示例代码和详细解释,建议参考学习,以加深对Java多线程的理解。

    Java多线程端口快速扫描

    Java多线程端口扫描是网络管理与安全领域中常用的一种技术,主要用于检测网络设备上哪些端口处于开放状态,从而分析网络的安全性或者优化网络配置。本程序通过利用Java的多线程特性,提高了扫描速度,使得在短时间内...

    java多线程.pdf

    ### Java多线程知识点详解 #### 一、Java多线程概述 **Java多线程**是指在Java程序中能够同时执行多个线程的技术。这种技术使得程序可以在多个任务之间并发执行,从而提高了程序的效率和资源利用率。本文将根据...

    java多线程设计模式_java_设计模式_多线程_多线程课题_

    Java多线程设计模式是Java开发中的核心概念,它涉及到如何高效、安全地在多个执行线程之间共享资源和协调任务。设计模式是解决特定问题的成熟方案,它们是编程经验的结晶,可以帮助开发者在面临多线程挑战时快速找到...

    精通java多线程

    Java多线程是Java编程语言中的一个重要特性,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在现代计算机系统中,多核处理器的普及使得多线程技术成为提升性能的关键手段。本篇将深入探讨Java多线程...

    Android多线程实现简单字符串计数器

    本示例“Android多线程实现简单字符串计数器”旨在教你如何在Android环境中利用多线程来实现一个简单的字符串计数器功能。 首先,我们需要理解Android中的线程模型。主线程,也称为UI线程,负责处理用户界面的更新...

    java多线程编程实例_Source

    通过这些实例,学习者能够深入理解Java多线程编程,提高解决实际并发问题的能力。每个章节的源码都是一个独立的案例,可以逐一研究,实践和调试,以便更好地掌握Java多线程编程技巧。在学习过程中,结合理论知识与...

    Java多线程资料

    Java多线程是Java编程中的核心概念,它允许程序同时执行多个任务,提高了软件的效率和响应性。在Java中,多线程的实现主要有两种方式:通过继承Thread类和实现Runnable接口。这篇资料深入探讨了Java多线程的相关知识...

    java多线程课件

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的并发性和效率。在Java中,线程是程序执行的基本单元,是轻量级的进程,它们共享同一份代码和数据空间,但每个线程有自己的栈和程序...

    JAVA多线程的实例

    Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应性。在Java中,实现多线程有两种主要方式:通过实现`Runnable`接口或者继承`Thread`类。 首先,让我们从创建线程开始。当你...

    java多线程进度条实例

    在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了效率。本实例将探讨如何利用Java实现一个具有进度条显示功能的多线程应用。进度条通常用于可视化地表示某个任务的完成程度,这对于长...

    java多线程_java多线程下变量共享_

    本篇文章将深入探讨Java多线程下变量共享的问题以及解决策略。 在Java中,线程共享变量可以通过两种方式实现:静态成员变量和实例成员变量。静态成员属于类,所有该类的实例都可以访问,因此在多线程环境下默认共享...

    Java 模拟线程并发

    最后,Java并发库还包含了很多其他有用的工具,如Semaphore(信号量)用于控制同时访问特定资源的线程数量,CyclicBarrier(循环屏障)和CountDownLatch(计数器门锁)用于多线程间的协作,以及Lock接口及其实现如...

Global site tag (gtag.js) - Google Analytics