总论
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多线程开发方式:pthread、NSThread、NSOperation及NSOperationQueue,以及Grand Central Dispatch(GCD)。 首先,让我们了解下pthread。pthread是POSIX线程库,它在iOS中被用于跨平台...
【Windows多线程总结】 Windows操作系统提供了一套完整的API来支持多线程编程,使得开发者可以在同一进程中同时执行多个线程,实现并发处理任务。本文将深入探讨Windows多线程编程的基本概念、线程同步、线程池以及...
### Java多线程问题总结 #### 一、多线程的作用与优势 1. **发挥多核CPU的优势:** - 当今计算机硬件普遍配备有多核CPU,利用多线程技术能够有效地分配任务到不同的核心上,使得计算资源得到最大化利用。在双核...
多线程基础理论, 多线程中常用API,多线程的实现方式, 线程池以及创建线程池相关API, 常见的设计模式等内容
### Java多线程知识点总结及企业真题解析 #### 一、知识点总结 ##### (1)多线程相关概念 1. **程序、进程和线程的区分**: - **程序**:为了完成特定的任务而编写的指令集合。它是静态的概念。 - **进程**:...
【Java 多线程学习详细总结】 在Java编程中,多线程是处理并发执行任务的关键技术。本文将深入探讨Java中的多线程概念、实现方式、线程状态转换、线程调度、线程同步以及数据传递等相关知识。 1. **扩展`java.lang...
QT提供了多种实现多线程的方式,其中QThread类是最常用的一种。本文将详细讲解如何在QT中使用QThread来优雅地创建和退出多线程。 一、QThread简介 QThread是QT中的一个类,用于提供线程功能。与标准C++库中的std::...
### Java多线程使用知识...总结来说,Java多线程是一种强大的工具,它可以帮助程序员有效地管理和控制并发执行的多个任务,提高程序的效率和响应能力。通过对线程的合理管理和利用,可以开发出高效、可靠的多线程应用。
总结,C#的多线程技术和模拟消息队列在上位机开发中起着至关重要的作用,它们能够优化性能,提高系统的响应速度,并为复杂任务的管理提供有效手段。理解并熟练运用这些技术,是成为一名合格的C#上位机开发者的关键。
这篇总结将深入探讨Java多线程的基础概念、特性以及常见用法,旨在为初学者提供一个全面的学习指南。 一、线程的基本概念 在Java中,线程是程序执行的最小单位,每个线程都有自己的程序计数器、虚拟机栈、本地方法...
在“Java多线程学习总结6”这个主题中,我们可以深入探讨Java多线程的实现、管理及优化。下面将详细阐述相关知识点。 1. **线程的创建方式** - **继承Thread类**:自定义类继承Thread类,并重写run()方法,创建...
- **2.2.2 使用POSIX的多线程**:利用标准POSIX API创建线程。 - **2.2.3 使用NSObject来生成一个线程**:通过继承`NSObject`并重写`performSelector:onThread:withObject:waitUntilDone:`方法来间接创建线程。 - **...
### 多线程服务器的几种常用模型 #### 1. 进程与线程 在计算机科学中,**进程**和**线程**是两个重要的概念。进程是资源分配的基本单位,而线程则是调度的基本单位。每个进程都有自己的独立地址空间,这意味着不同...
总结来说,《Win32多线程程序设计》不仅是一本介绍理论和技术的书籍,它还提供了大量实例和案例分析,帮助读者深入理解多线程程序设计的各个方面。对于那些希望开发高性能、响应迅速的应用程序,尤其是服务器端程序...
对于一些常用的框架,如Foundation Framework、ApplicationKit和CoreData,Apple提供了线程安全的总结,指导开发者如何在这些框架内安全地使用多线程。 以上就是iOS多线程编程指南的主要知识点,详细解读了多线程...
### 并发服务器—多线程服务器详解 #### 一、引言 在现代软件开发中,特别是网络应用和服务的设计中,对并发处理能力的需求日益增长。为了满足高并发访问的需求,开发人员常采用多线程技术来构建高效、响应迅速的...
总结起来,虽然Shell本身不支持多线程,但我们可以通过FIFO文件和进程间的通信来模拟多线程行为,实现批量处理任务,例如在当前目录下批量插入MySQL数据库。这种方法在处理大量并发任务时非常有用,提高了工作效率。
标题中的“关于多线程的专用书籍是真的”表明这是一本专门探讨多线程编程的书籍,而描述中的“多线程的专用书籍这是很好的”进一步确认了这本书的专业性和价值。多线程是计算机编程中一个重要的概念,尤其是在并发...
### C#多线程教材知识点详解 ...以上是对C#多线程教材的详细知识点总结,涵盖了从基本概念到高级主题的相关内容。掌握这些知识将有助于开发者更好地利用多线程技术,构建高效、可靠的多线程应用程序。