1、进程是程序的一次动态执行过程,这个过程也是进程本身从产生到消亡的过程。
2、由于cpu有“分时机制”,所以每个程序都能循环获得cpu的时间片段。加之CPU的执行速度快,感觉上像是同时在运行。
3、多线程是实现并发机制的一种有效手段,线程是比进程更小的执行单位,是进程的基础上进一步的划分。
4、一个进程可能包含多个同时执行的线程。
5、main()函数开始运行的线程为主线程。
6、 在Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)。他们之间的区别在于JVM。
7、用户线程:所有用户线程结束,jvm关闭;
8、守护线程:只有守护线程了,jvm可以关闭(也就是说守护线程不依赖于终端,但是依赖于系统,与系统“同生共死”)。
9、守护线程是后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程。用户线程可以理解为是系统的工作线程,它会完成这个程序需要完成的业务操作。
10、通过Thread.setDaemon(false)设置为用户线程,通过Thread.setDaemon(true)设置为守护线程。
1、线程创建之后,进入新建状态,jvm给他分配内存空间,并且进行初始化。当线程对象的start()方法被调用,线程就处于可执行状态。
2、处于可执行状态的线程,随时可被CPU调度执行。
3、CPU执行该线程的时候,线程进入执行状态。中间可能会进入阻塞状态或者就绪状态。
4、直至线程异常或者线程正常结束或者return了数据。线程结束,整个生命周期结束。
1、继承Thread类,重写run()方法
class FrozenTread extends Thread { @Override public void run(){ dosomething(); } } //调用 FrozenTread item = new FrozenTread(); item.start();2、实现Runnable接口,重写run()
//1):定义一个类A实现于java.lang.Runnable接口,注意A类不是线程类. class FrozenImplements implements Runnable{ //2):在A类中覆盖Runnable接口中的run方法. @Override public void run() { //3):在run方法中编写需要执行的操作 dosomething(); } } //调用 FrozenImplements item = new FrozenImplements(); Thread thread = new Thread(item); thread.start();3、直接在函数体使用
//单CPU创建10个线程 ExecutorService pool = Executors.newFixedThreadPool(10); pool.execute(new Runnable() { @Override public void run() { dosomething(); } } pool.shutdown(); while(true){ if(pool.isTerminated()){ break; } }或者
Thread t = new Thread(new Runnable(){ @Override public void run(){ // run方法具体重写 dosomething(); }}); t.start();新鲜供测试的数据库
1、常规写法,不开启新线程
public String aaa(){ long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { try { String sql = "insert into ceshi(uuid,test,name,age) values(1234,'22222','2020年7月1日15:46:14',123)"; jdbcTemplate.execute(sql); }catch (Exception e){ e.printStackTrace(); } } long end = System.currentTimeMillis(); String abc= end - start+"毫秒"; System.out.println(abc); return abc; }2、使用ExecutorService,开启10个线程
ExecutorService共有四种线程池:CachedThreadPool可缓存线程池、SingleThreadExecutor单线程池、FixedThreadPool固定线程数线程池、ScheduledThreadPool 固定线程数,支持定时和周期性任务线程池。
public String bbb(){ long start = System.currentTimeMillis(); ExecutorService pool = Executors.newFixedThreadPool(10); pool.execute(new Runnable() { @Override public void run() { for (int i = 0; i < 10000; i++) { try { String sql = "insert into ceshi(uuid,test,name,age) values(1234,'22222','哈哈哈多喝点',123)"; jdbcTemplate.execute(sql); }catch (Exception e){ e.printStackTrace(); } } } }); pool.shutdown(); String abc; while(true){ if(pool.isTerminated()){//终结者 long end = System.currentTimeMillis(); abc= end - start+"毫秒"; System.out.println(abc); break; } } return abc; }数据成功插入
3、实现java.lang.Runnable接口,开启两个线程
//1):定义一个类A实现于java.lang.Runnable接口,注意A类不是线程类. class FrozenImplements implements Runnable{ //2):在A类中覆盖Runnable接口中的run方法. @Override public void run() { //3):在run方法中编写需要执行的操作 for (int i = 0; i < 5000; i++) { try { String sql = "insert into ceshi(uuid,test,name,age) values(1234,'22222','哈哈哈多喝点',123)"; jdbcTemplate.execute(sql); }catch (Exception e){ e.printStackTrace(); } } } } public String ddd(){ long start = System.currentTimeMillis(); try { FrozenImplements item = new FrozenImplements(); Thread thread = new Thread(item); Thread thread1 = new Thread(item); thread.start(); thread1.start(); //一个线程在启动后就马上执行,必须调用 Thread.Join()方法 thread.join(); thread1.join(); }catch (Exception e){ e.printStackTrace(); } long end = System.currentTimeMillis(); return end- start +"毫秒"; }数据成功插入
1、从上面的实现我们可以看出,开启多个线程,表面上执行效率是有所提高。
2、我们的计算机,一般只有一个CPU。多线程只不过是CPU在不同时间片之间的切换和调度。快慢未可知。
3、是不是说开启多个线程,效率就高了或者因为CPU的切换和调度变慢了。这个问题无法给你准确的答案,CPU是和其他硬件设备一起工作的。多线程的目的可以最大限度的提高硬件设备的利用率。
4、也就是说,一个单CPU。多线程是否有效率在于,CPU的效率和其他配合硬件的效率。这是一个不断优化,依照实际情况而定的过程(开启几个线程,是否需要开启线程)。
5、多个cpu的时候,计算机适当多开启几个线程同时处理,会提高效率。
6、服务器端最佳线程数量=((线程等待时间+线程cpu时间)/线程cpu时间) * cpu数量