`

java使用多线程同时插入数据库数据例子

 
阅读更多

今天自己在家准备面试内容,写了个java使用多线程往mysql数据库插入数据的例子:

总结:

不管数据库引擎是MYISAM还是InnoDB,情况都是

没有线程池的情况下就不说了,一直创建数据库连接一会就出错了,基本对于上万条的数据插入不可用。

使用线程池,开启多个线程并发执行的效率是明显高于单线程的插入的,所以对于大数据量数据迁移的情况下使用并发线程池还是很能提高效率的。

 

小弟新手,有什么错误还请指明,谢谢。

 

以下是测试内容:

表结构:

表引擎:MyISAM



 

程序代码:

自己写了个简单的线程池,在使用线程池之前插入一万条数据的时间是(并发没有线程池:所有线程执行完毕:16663),没写线程池之前的代码就不上传了,就是简单的jdbc连接,下面是使用线程池的代码:

JdbcUtils.java

package com.inserttestdata;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Vector;

public class JdbcUtils {
	static String driver = "com.mysql.jdbc.Driver";
	static String url="jdbc:mysql://localhost:3306/test";
	static String user="root";
	static String pwd = "123456";
	
	static Vector<Connection> pools = new Vector<Connection>();
	
	public static Connection getDBConnection(){
		try {
			//1.加载驱动
			Class.forName(driver);
			//2.取得数据库连接
			Connection conn =  DriverManager.getConnection(url, user, pwd);
			return conn;
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	static {
		int i = 0;
		while(i<10){
		pools.add(getDBConnection());
		i++;
		}
	}
	
	public static synchronized Connection getPool(){
		if(pools != null && pools.size() > 0){
			int last_ind = pools.size() -1;
			return pools.remove(last_ind);
		}else{
			return getDBConnection();
		}
	}
	
	public static int insert(String sql,Object[] params){
		Connection conn = getPool();
		PreparedStatement pstmt = null;
		try {
			pstmt = conn.prepareStatement(sql);
			for(int i=0;i<params.length;i++){
				pstmt.setObject(i+1, params[i]);
			}
			return pstmt.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			if(pstmt != null){
				try {
					pstmt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			
			if(conn != null){
//					conn.close();
					pools.add(conn);
			}
		}
		return 0;
	}
}

 测试类的代码:

doInsert.java

package com.inserttestdata;

import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class doInsert {
	public static void main(String[] args) {
		long startTimes = System.currentTimeMillis();
		String[] names = new String[]{"LXL","MQJ","JOE","JON","JACK","LILY","LUCY","NOB","FDSE","GTX"};
		int threadCount = 10;
		int total = 100000;
		int every = total/threadCount;
		final CountDownLatch latch = new CountDownLatch(threadCount);
//		ExecutorService executor = Executors.newFixedThreadPool(10);
		for(int i=0;i<threadCount;i++){
			new Thread(new Worker(latch,names[i],i*every,(i+1)*every)).start();
		}
		try {
			latch.await();
			long endTimes = System.currentTimeMillis();
			System.out.println("所有线程执行完毕:" + (endTimes - startTimes));
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	
	
}

class Worker implements Runnable{
	
	static String sql = "INSERT INTO `tb_demo` (`name`,cre_date) VALUES (?, ?);";
	int start = 0;
	int end = 0;
	String name = "";
	CountDownLatch latch;
	public Worker(CountDownLatch latch,String name, int start,int end){
		this.start = start;
		this.end = end;
		this.name = name;
		this.latch = latch;
	}
	
	@Override
	public void run() {
		for (int i = start; i < end; i++) {
			System.out.println("线程" + Thread.currentThread().getName()+ "正在执行。。");
			Object[] params = new Object[] { name + i, new Date() };
			JdbcUtils.insert(sql, params);
		}
		latch.countDown();
	}
	
}

 使用线程池并且开启10个线程插入十万条数据的时间是:



 下面是使用线程池但只有一个线程的情况下的测试时间:

只需要将main函数中的int threadCount = 10;改为int threadCount = 1;就可以了,

 

 

测试结果:

(MYISAM)并发没有线程池:所有线程执行完毕:16663ms

(MYISAM)并发使用线程池:所有线程执行完毕:4194ms

(MYISAM)单线程使用线程池:所有线程执行完毕:14667ms

 

将表的引擎改为InnoDB后测试10000条数据的插入操作:

(InnoDB)并发使用线程池:所有线程执行完毕:74968ms

InnoDB单线程使用线程池:所有线程执行完毕:481712ms

 

总结:

不管数据库引擎是MYISAM还是InnoDB,情况都是:

没有线程池的情况下就不说了,一直创建数据库连接一会就出错了,基本对于上万条的数据插入不可用。

使用线程池,开启多个线程并发执行的效率是明显高于单线程的插入的,所以对于大数据量数据迁移的情况下使用并发线程池还是很能提高效率的。

 

小弟新手,有什么错误还请指明,谢谢。

另外我今天搜到一个这样的结果,是我理解的错了还是他的回答错了呢,求证一下:

http://zhidao.baidu.com/link?url=XMyaFELOmEIkkEAeNZWfgJKM8jTinhimX8vzwXaXcRiTcvD_YzWVm6jW923Ev2wmOPaUL0EfxyWRXhwccoQMaq

内容如下:



 

  • 大小: 14.8 KB
  • 大小: 4.1 KB
  • 大小: 6 KB
  • 大小: 156.4 KB
分享到:
评论

相关推荐

    插入数据多线程例子

    本示例主要探讨如何在数据库操作中实现多线程插入数据,以提高效率和性能。多线程能让我们充分利用现代多核处理器的计算能力,使得任务能够并行执行,从而缩短整体的执行时间。 在“插入数据多线程例子”中,我们...

    Android读取数据库数据例子

    在Android应用开发中,通常使用SQLite数据库来存储和管理应用程序中的数据。然而,如果你需要连接到远程MySQL数据库,情况会有所不同。这篇长文将详细解释如何在Android应用中读取MySQL数据库的数据,以及相关的知识...

    java多线程并发编程例子

    Java多线程并发编程是Java开发中的重要领域,特别是在服务器端和高并发应用中不可或缺。`java.util.concurrent`包提供了丰富的工具类,帮助开发者更好地管理线程和优化并发性能。以下将详细介绍标题和描述中涉及的...

    java多线程应用实战

    多线程在实际开发中有着举足轻重的作用,但在教科书中并没有学到,本文以mysql(支持任何数据库)插入数据和查询数据为例子,讲述了如何在几秒钟内疯狂插入几十万数据,在一个方法中如何同时运行多条SQL语句(效率比...

    使用DAO访问数据库的例子(189KB)

    在多线程环境下,为了保证数据的一致性,可能需要使用事务来包裹一系列的数据库操作。Java的JDBC API提供了Connection对象的commit()和rollback()方法来控制事务的提交和回滚。 除此之外,我们还可能看到使用了...

    Java+mysql本地图片上传数据库及下载示例

    这个例子提供了一个基础的实现,但在实际项目中,可能需要考虑更多因素,如错误处理、多线程、文件大小限制、安全性等。此外,对于大型项目,通常不推荐将图片直接存储在数据库中,而是采用文件系统或云存储服务,...

    java多線程導入不同csv文件到不同表1

    总的来说,"java多线程導入不同csv文件到不同表1"项目涉及了Java多线程编程、CSV文件处理、数据库操作和异常处理等多个核心知识点,是学习和实践这些技能的好例子。通过优化和扩展这个项目,我们可以构建出更高效、...

    实例讲解Java批量插入、更新数据

    在Java编程中,批量插入和更新数据是数据库操作中常见的需求,尤其是在处理大量数据时,可以显著提高效率。本文将通过一个具体的实例来探讨如何在Java中实现对Oracle数据库的批量数据操作。 首先,批量插入数据通常...

    HIbernate与oracle数据库应用例子

    通过上述步骤,开发者可以在Java应用中高效地使用Hibernate与Oracle数据库进行数据操作。实践过程中,应不断优化和调整,以适应不同场景的需求。在实际项目中,还需要关注性能监控、异常处理、安全防护等方面,确保...

    java导出例子

    在Java编程语言中,"导出例子"通常指的是...综上所述,Java 导出例子涵盖了许多编程实践,从基本的文件操作到更复杂的数据格式转换、多线程处理等。理解并熟练掌握这些知识点,对于进行高效、安全的数据导出至关重要。

    一个串口通讯数据库存取例子程序.zip

    7. **并发处理**:如果需要同时处理多个串口通信或者多个数据库操作,就需要考虑多线程或异步编程,以提高程序的效率。 这个压缩包中的例子程序很可能是为了教学目的而创建的,它可能包含了一个简单的串口通信模块...

    多进程写sqlite互斥解决方案代码

    然而,当多个进程或线程同时尝试写入SQLite数据库时,可能会引发数据冲突和不一致,因为SQLite本身并不提供内置的多进程或多线程同步机制。为了解决这个问题,我们需要自定义锁或者其他同步原语来确保数据的一致性。...

    Java程序例子

    6. **线程编程**: Java内置了对多线程的支持,例子可能包含线程的创建、同步、生命周期管理,帮助理解并发编程。 7. **反射机制**: 反射允许在运行时检查类的信息,创建和调用对象。示例可能展示如何动态地获取类、...

    ObjectBox的例子AndroidJava的超高速数据库.zip

    在这个“ObjectBox的例子AndroidJava的超高速数据库.zip”压缩包中,包含了帮助开发者理解和应用ObjectBox的实例代码和相关说明。 首先,我们来看一下ObjectBox的核心特性。ObjectBox采用了独特的对象持久化模型,...

    java 操作excel的例子

    在Java编程中,操作Excel是一项常见的任务,尤其在数据处理、报表生成或数据导入导出时。...当然,实际应用中可能还需要考虑更多的细节,比如错误处理、数据验证、多线程处理等,以满足更复杂的需求。

    多线程的批量线程同步解决方案

    "多线程的批量线程同步解决方案"这个标题暗示我们探讨的是如何在多线程环境下有效地管理和同步多个任务,确保数据一致性与程序正确性。下面将详细阐述相关知识点。 一、多线程基础 多线程是指在一个进程中同时执行...

    如何处理多个更新或插入数据库

    总之,处理多个更新或插入到数据库时,关键在于理解事务的使用、错误处理和恢复策略,以及优化数据库交互的方法。通过合理地运用这些技术,可以确保数据操作的可靠性和效率,即使在面临网络中断等挑战时也能保证数据...

    java 多线程之生产者与消费者

    Java多线程中的“生产者与消费者”模式是一种经典的并发编程模型,用于解决资源的生产与消费问题。在这个模式中,生产者线程负责创建或生成数据,而消费者线程则负责处理或消耗这些数据。这种模式充分利用了系统资源...

    csv导入数据库 java源代码

    这时可以考虑分块读取文件,或者使用多线程并行处理。 此外,如果你的数据库支持批量插入,利用批处理可以显著提高导入效率。同时,根据实际情况,可能还需要处理空值、异常字符等问题。 总之,将CSV文件导入...

    ImportFile.rar

    总结来说,"ImportFile.rar"的工程实例展示了Java多线程技术在处理大量文件并将其数据插入数据库时的应用。它涉及了线程的创建与管理、文件操作、数据库交互以及并发控制等多个核心概念,是学习和实践Java并发编程的...

Global site tag (gtag.js) - Google Analytics