`
guanpanpan
  • 浏览: 16969 次
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

常用的多线程使用方式总结

 
阅读更多

总论

1.可以不用多线程最好不要用

2.如果可以不共享数据最好不要共享

3.服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量

因为数据库访问等待造成线程等待时间长比较长见,下面的例子就是以数据库数据迁徙程序说明。

常用模式

1.分几个线程处理不同数据

适用场景:数据可以容易的分开处理

		int dbMax = 10;
		int tableMax = 16;
		ExecutorService executorService = Executors.newFixedThreadPool(40);
		latch = new CountDownLatch(dbMax * tableMax);
		for (int tableNo = 1; tableNo <= tableMax; tableNo++) {
			for (int dbNo = 1; dbNo <= dbMax; dbNo++) {
				// 启动线程
				executorService.execute(new UserinfoRunable(dbNo, tableNo));

			}
		}
		executorService.shutdown();
		try {
			latch.await();
		} catch (InterruptedException e1) {
			log.error("threadLatch.await()", e1);
		}
		log.info("main End");

 下类省去了部分代码

	static class UserinfoRunable implements Runnable {
		int dbNo;
		int tableNo;

		public UserinfoRunable(int dbNo, int tableNo) {
			this.dbNo = dbNo;
			this.tableNo = tableNo;
		}

		@Override
		public void run() {
			while (opSize == bantchSize) {
				log.debug("db-table:" + dbNo + "-" + tableNo + " dealSize:" + dealNum);
				//省去代码
			}                    
			latch.countDown();
		}
}

 

2.线程协作来处理同一批数据

适用场景:数据处理是一个类似生产线情况,每个生产过程费时不同

数据操作方法

package com.jd.sns.dc.common;

import java.util.Collection;
import java.util.concurrent.BlockingQueue;

/**
 * 阻塞队列
 * @author guanpanpan
 *
 */
public class BlockingQueueUtil {
	/**
	 * 向队列加入一组数据,如果对队已满会阻塞
	 */
	public static <T> void add(BlockingQueue<T> blockingQueue, Collection<T> collection) throws InterruptedException {
		for (T object : collection) {
			blockingQueue.put(object);
		}
	}

	/**
	 * 向队列加入单个数据,如果对队已满会阻塞
	 */
	public static <T> void add(BlockingQueue<T> blockingQueue, T object) throws InterruptedException {
		blockingQueue.put(object);
	}
}

 

BlockingQueue<ChangeLogBantch> idBantchQueue = new LinkedBlockingQueue<ChangeLogBantch>(1000);

 

 

 取数据

while (run) {
				try {
					List<ChangeLog> changeLogs = changeLogDao.getChangeLogs1(dbNo, checkStartId, checkIdBantchCount);
					List<ChangeLogBantch> idBantchBeans = ChangeLogBantch.createIdBantchBeanList(dbNo, DcConst.BANTCH_COUNT,
							changeLogs, true);
					// 当取出的数据不满批查询数量的时候,认为这次的增量校验完成
					if (changeLogs.size() < checkIdBantchCount) {
						run = false;
					}
					// 更新最大ID
					if (idBantchBeans.size() > 0) {
						// 遍历,获得这次取出的最大的ID,作为下次查询的参数
						checkStartId = changeLogs.get(changeLogs.size() - 1).getChangeLogId();
						log.debug("idGeter:" + idBantchBeans);
						dataGeter.addIdBantchAll(idBantchBeans);
					}
				} catch (Exception ex) {
					log.error("Error in read db!", ex);
				}
			}
			IdGeter.idGeterLatch.countDown();

 

 消费数据

	/**
	 * 获取一个IDBantchBean 非阻塞式调用,返回null表示已拿完
	 */
	public ChangeLogBantch getIdBantch() {
		return idBantchQueue.poll();
	}

 

		public void run() {
			log.debug("get CompareBeans start" + ThreadUtil.getLogName());
			while (run) {
				ChangeLogBantch idBantch = getIdBantch();
				if (idBantch == null) {
					if (!ID_GETER_RUN) {
						run = false;
					}
				} else {
					try {
						List<CompareBean> compareBeans = checkService.getCompareBeans(idBantch);
						dataCompareter.addCompareBean(compareBeans);
						log.debug("CompareBeans:" + ThreadUtil.getLogName() + compareBeans);
						// 两边都为空的数据记录日志
						CkDataGeter.notInChangeLogIds.addAll(checkService.getNotInChangeLogIds(idBantch, compareBeans));
					} catch (SQLException e) {
						log.error("Get data from db error!", e);
						// 出错后将这批ID放回队列中
						addIdBantch(idBantch);
					}
				}
			}
			log.debug("get CompareBeans end" + ThreadUtil.getLogName());
			CkDataGeter.dataGeterLatch.countDown();
		}

 附一:使用取模来实现多线程处理不同数据

	@Override
	public long getMode(String pin, int modeSize) {
		return getHash(pin) % modeSize + 1;
	}

 

			if (modeNo != routeUtil.getMode(pin, modeSize)) {
				continue;
			}

 

分享到:
评论

相关推荐

    ios多线程开发的常用四种方式和基本使用

    本文将深入探讨四种常用的iOS多线程开发方式:pthread、NSThread、NSOperation及NSOperationQueue,以及Grand Central Dispatch(GCD)。 首先,让我们了解下pthread。pthread是POSIX线程库,它在iOS中被用于跨平台...

    windows多线程总结

    【Windows多线程总结】 Windows操作系统提供了一套完整的API来支持多线程编程,使得开发者可以在同一进程中同时执行多个线程,实现并发处理任务。本文将深入探讨Windows多线程编程的基本概念、线程同步、线程池以及...

    40个Java多线程问题总结

    ### Java多线程问题总结 #### 一、多线程的作用与优势 1. **发挥多核CPU的优势:** - 当今计算机硬件普遍配备有多核CPU,利用多线程技术能够有效地分配任务到不同的核心上,使得计算资源得到最大化利用。在双核...

    多线程基础总结.xmind

    多线程基础理论, 多线程中常用API,多线程的实现方式, 线程池以及创建线程池相关API, 常见的设计模式等内容

    Java多线程-多线程知识点总结和企业真题

    ### Java多线程知识点总结及企业真题解析 #### 一、知识点总结 ##### (1)多线程相关概念 1. **程序、进程和线程的区分**: - **程序**:为了完成特定的任务而编写的指令集合。它是静态的概念。 - **进程**:...

    Java 多线程学习详细总结

    【Java 多线程学习详细总结】 在Java编程中,多线程是处理并发执行任务的关键技术。本文将深入探讨Java中的多线程概念、实现方式、线程状态转换、线程调度、线程同步以及数据传递等相关知识。 1. **扩展`java.lang...

    QT多线程的实现方式:QThread run优雅的创建与退出QT多线程

    QT提供了多种实现多线程的方式,其中QThread类是最常用的一种。本文将详细讲解如何在QT中使用QThread来优雅地创建和退出多线程。 一、QThread简介 QThread是QT中的一个类,用于提供线程功能。与标准C++库中的std::...

    java多线程使用

    ### Java多线程使用知识...总结来说,Java多线程是一种强大的工具,它可以帮助程序员有效地管理和控制并发执行的多个任务,提高程序的效率和响应能力。通过对线程的合理管理和利用,可以开发出高效、可靠的多线程应用。

    c# 多线程 上位机

    总结,C#的多线程技术和模拟消息队列在上位机开发中起着至关重要的作用,它们能够优化性能,提高系统的响应速度,并为复杂任务的管理提供有效手段。理解并熟练运用这些技术,是成为一名合格的C#上位机开发者的关键。

    Java多线程的总结

    这篇总结将深入探讨Java多线程的基础概念、特性以及常见用法,旨在为初学者提供一个全面的学习指南。 一、线程的基本概念 在Java中,线程是程序执行的最小单位,每个线程都有自己的程序计数器、虚拟机栈、本地方法...

    Java 多线程学习总结6

    在“Java多线程学习总结6”这个主题中,我们可以深入探讨Java多线程的实现、管理及优化。下面将详细阐述相关知识点。 1. **线程的创建方式** - **继承Thread类**:自定义类继承Thread类,并重写run()方法,创建...

    多线程编程指南

    - **2.2.2 使用POSIX的多线程**:利用标准POSIX API创建线程。 - **2.2.3 使用NSObject来生成一个线程**:通过继承`NSObject`并重写`performSelector:onThread:withObject:waitUntilDone:`方法来间接创建线程。 - **...

    多线程服务器的几种常用模型

    ### 多线程服务器的几种常用模型 #### 1. 进程与线程 在计算机科学中,**进程**和**线程**是两个重要的概念。进程是资源分配的基本单位,而线程则是调度的基本单位。每个进程都有自己的独立地址空间,这意味着不同...

    win32多线程程序设计 pdf

    总结来说,《Win32多线程程序设计》不仅是一本介绍理论和技术的书籍,它还提供了大量实例和案例分析,帮助读者深入理解多线程程序设计的各个方面。对于那些希望开发高性能、响应迅速的应用程序,尤其是服务器端程序...

    ios 多线程编程指南

    对于一些常用的框架,如Foundation Framework、ApplicationKit和CoreData,Apple提供了线程安全的总结,指导开发者如何在这些框架内安全地使用多线程。 以上就是iOS多线程编程指南的主要知识点,详细解读了多线程...

    并发服务器-多线程服务器详解

    ### 并发服务器—多线程服务器详解 #### 一、引言 在现代软件开发中,特别是网络应用和服务的设计中,对并发处理能力的需求日益增长。为了满足高并发访问的需求,开发人员常采用多线程技术来构建高效、响应迅速的...

    shell的多线程&当前文件夹下批量插入MySQL

    总结起来,虽然Shell本身不支持多线程,但我们可以通过FIFO文件和进程间的通信来模拟多线程行为,实现批量处理任务,例如在当前目录下批量插入MySQL数据库。这种方法在处理大量并发任务时非常有用,提高了工作效率。

    关于多线程的专用书籍是真的

    标题中的“关于多线程的专用书籍是真的”表明这是一本专门探讨多线程编程的书籍,而描述中的“多线程的专用书籍这是很好的”进一步确认了这本书的专业性和价值。多线程是计算机编程中一个重要的概念,尤其是在并发...

    C# 多线程教材

    ### C#多线程教材知识点详解 ...以上是对C#多线程教材的详细知识点总结,涵盖了从基本概念到高级主题的相关内容。掌握这些知识将有助于开发者更好地利用多线程技术,构建高效、可靠的多线程应用程序。

Global site tag (gtag.js) - Google Analytics