线程

多线程就是一个程序中有多个线程在同时执行。

多线程下CPU的工作原理

实际上,CPU(中央处理器)使用抢占式调度模式在多个线程间进行着高速的切换。对于CPU的一个核而言,某个时刻,只能执行一个线程,而CPU的在多个线程间切换速度相对我们的感觉要快,看上去就是在同一时刻运行。

其实,多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高。

一、创建线程

方法1:继承Thread类,重写run方法

public class SubThread extends Thread{public SubThread(){super("x5456");     //通过构造方法修改线程名}public void run() {for(int i=0;i<100;i++){System.out.println(super.getName()+i);}}
}

调用:

public static void main(String[] args) {//创建刚刚继承Thread类的子类的对象SubThread st = new SubThread();//通过setName方法,修改线程名st.setName("x54256");//调用对象的start方法,会自动执行我们重写的run方法st.start();for(int i=0;i<100;i++) {System.out.println(Thread.currentThread().getName()+i);     //获取当前线程的对象,调用getname()方法}
}

方法2:实现接口Runnable,重写run方法

public class SubRunnable implements Runnable{public void run(){for(int i=0;i<100;i++){try {// 调用Thread类的sleep方法,休眠50ms,由于父接口没有throws异常,so我们只能用try...catchThread.sleep(50);  } catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"..."+i);}}
}

调用:

public static void main(String[] args) {//创建实现Runnable接口的类的对象SubRunnable sr = new SubRunnable();//创建Thread类的对象Thread t = new Thread(sr);//启动线程t.start();for(int i=0;i<100;i++){System.out.println(Thread.currentThread().getName()+"..."+i);}
}

方法3:使用匿名内部类,实现多线程程序

匿名内部类的前提:继承或者接口实现

使用方法:

new 父类或者接口(){
  重写抽象方法
}

public static void main(String[] args) {//继承方式  XXX extends Thread{ public void run(){}}new Thread(){public void run(){System.out.println("!!!");}}.start();//实现接口方式  XXX implements Runnable{ public void run(){}}Runnable r = new Runnable(){public void run(){System.out.println("###");}};new Thread(r).start();//==================或=====================new Thread(new Runnable(){public void run(){System.out.println("@@@");}}).start();} 

实现接口的好处:

高内聚,低耦合:模块内能做的事就自己做,模块间的关系要尽量的小

第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。继承Thread类,线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。实现runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。Runnable接口对线程对象和线程任务进行解耦。

多线程的内存图解:

线程的一生:

二、线程池

线程池,其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。

在java中,如果每个请求到达就创建一个新线程,开销是相当大的。在实际使用中,创建和销毁线程花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多。除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源。如果在一个jvm里创建太多的线程,可能会使系统由于过度消耗内存或“切换过度”而导致系统资源不足。为了防止资源不足,需要采取一些办法来限制任何给定时刻处理的请求数目,尽可能减少创建和销毁线程的次数,特别是一些资源耗费比较大的线程的创建和销毁,尽量利用已有对象来进行服务。

线程池主要用来解决线程生命周期开销问题和资源不足问题。通过对多个任务重复使用线程,线程创建的开销就被分摊到了多个任务上了,而且由于在请求到达时线程已经存在,所以消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使用应用程序响应更快。另外,通过适当的调整线程中的线程数目可以防止出现资源不足的情况。

方法1:使用线程池方式--Runnable接口

public static void main(String[] args) {//调用工厂类的静态方法,创建线程池对象(ExecutorService接口的实现类)//返回线程池对象,是返回的接口ExecutorService es = Executors.newFixedThreadPool(2);  //池内有2个线程//调用接口实现类对象es中的方法submit提交线程任务//将Runnable接口实现类对象,传递es.submit(new SubRunnable());es.submit(new SubRunnable());es.submit(new SubRunnable());es.submit(new SubRunnable());
}

实现的Runnable接口

public class ThreadPoolRunnable implements Runnable {public void run(){System.out.println(Thread.currentThread().getName()+" 线程提交任务");}
}

方法2:使用线程池方式—Callable接口

之前的实现方法,线程运行完没有返回值,而且不能抛异常。

Callable接口:与Runnable接口功能相似,用来指定线程的任务。其中的call()方法,用来返回线程任务执行完毕后的结果,call方法可抛出异常。

public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService es = Executors.newFixedThreadPool(2);//提交线程任务的方法submit方法返回 Future接口的实现类Future<Integer> f = es.submit(new SubCallable());//获取返回值Integer i = f.get();System.out.println(i);
}

实现的Callable接口

public class SubCallable implements Callable<Integer>{@Overridepublic Integer call() {return 123;}
}

使用线程实现异步计算

private int a;
//通过构造方法传参
public GetSumCallable(int a){this.a=a;
}public Integer call(){int sum = 0 ;for(int i = 1 ; i <=a ; i++){sum = sum + i ;}return sum;
}

ThreadPoolDemo.java

/** 使用多线程技术,求和* 两个线程,1个线程计算1+100,另一个线程计算1+200的和* 多线程的异步计算*/
public class ThreadPoolDemo {public static void main(String[] args)throws Exception {ExecutorService es = Executors.newFixedThreadPool(2);Future<Integer> f1 =es.submit(new GetSumCallable(100));Future<Integer> f2 =es.submit(new GetSumCallable(200));System.out.println(f1.get());System.out.println(f2.get());es.shutdown();}
}

FutureTask的使用

FutureTask继承了Callable和Future接口,所以它既能像callable一样被Thread执行,也能像Future那样获取结果。

    @Overridepublic boolean testServiceUrl(ServiceUrlTestDTO url){// 调用地图服务Callable<Boolean> callable = new WebServiceUtil(url.getUrl(),url.getProxy(),url.getToken());FutureTask<Boolean> futureTask = new FutureTask<>(callable);Thread thread = new Thread(futureTask);thread.start();try {Boolean isOK = futureTask.get();System.out.println("服务【"+ url.getUrl() +"】测试:"+ isOK);return isOK;} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}return false;}

  

转载于:https://www.cnblogs.com/x54256/p/8443794.html

Java——线程的创建,线程池相关推荐

  1. java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?

    java 线程中创建线程 在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet. java.util.concurrent包甚至没有一个名为Concurren ...

  2. java线程的创建线程_多线程(Thread、线程创建、线程池)

    第1章 多线程 1.1 多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序, ...

  3. Java 通过Executors创建线程池的种类

    java通过Executors可以创建四种线程池: newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需求,可灵活回收空闲线程,若无可回收,则新建线程. newFix ...

  4. java 线程中创建线程_java – 在线程中创建线程 – 良好的做​​法?

    参见英文答案 > Threads within threads in Java?                                    4个 在线程中启动线程是一种好习惯吗?我搜 ...

  5. 如何在Java 8中创建线程安全的ConcurrentHashSet?

    在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet. java.util.concurrent包甚至没有一个名为ConcurrentHashSet的类,但是 ...

  6. java中怎样创建线程_java中的线程创建和使用

    Java中实现多线程有两种途径:继承Thread类或者实现Runnable接口.Runnable是接口,建议用接口的方式生成线程,因为接口可以实现多继承,况且Runnable只有一个run方法,很适合 ...

  7. java for循环创建线程_Java创建线程的两种方法

    大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: 实现Runnable 接口: 可以继承Thread类. 下面的两小节依次介绍了每一种方式. 实现Runnable接口 ...

  8. java 创建5个线程_Java创建线程的三种方式

    1.继承Thread 类,创建线程类 ,调用start方法启动  (单一继承 ) public class Test1 extendsThread { @Overridepublic voidrun( ...

  9. JAVA笔记13__创建线程/线程休眠/等待线程终止/线程中断/守护线程

    /*** 线程:是进程的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行,一个进程最少有一个进程(单线程程序)* 多线程两种实现方法:1.继承Thread类 2.实现Runnable接口 ...

  10. 020.day20 线程概述 多线程优缺点 线程的创建 线程常用方法 生命周期 多线程同步...

    目录 多线程 一.线程概述 四.线程常用方法 多线程 一.线程概述 1. 进程 正在执行的应用程序(java.exe),一个可执行的程序一次运行的过程 独立性:不同进程之间相互独立 动态性:是一直活动 ...

最新文章

  1. ubuntu12.04安装node.js详细步骤
  2. stl max函数_C ++ STL中带有示例的array :: max_size()函数
  3. CF1228C. Primes and Multiplication(数学)
  4. 基础Floyd--任意两点间最短路
  5. 手机访问电脑虚拟服务器,User Agent Switcher插件使用教程【电脑模拟手机访问网站】...
  6. Ubuntu常见错误合集——持续更新
  7. 海康大华ie插件开发
  8. 用python做外贸
  9. 牛逼!这个C++跳棋游戏居然可以让你边玩游戏边学编程!
  10. android手机固件升级原理,为什么常说Android手机千万别频繁的系统升级,背后的真实原因?...
  11. stm8l051 halt之后外部中断唤醒问题
  12. 迅搜中文分词简明教程
  13. 云创以炫酷软件和饕餮美食喜迎新年!
  14. Esp32Cam WebServer 网页源代码查看与编辑
  15. Learning to Quantize Deep Networks by Optimizing Quantization Intervals with Task Loss 论文总结
  16. 苹果cms vod_list修改
  17. 操作系统之设备管理简介
  18. 零伽壹 | 福州出台打造国内一流枢纽机场等16个重大项目行动方案
  19. 使 ASP.NET Web 站点易于访问
  20. 三招两式搞定修改VC项目名

热门文章

  1. oracle sparc 服务器系统,OracleSPARC服务器基础.PDF
  2. java中的并发类_java中并发常用工具类
  3. 【最小费用可行流模板】
  4. 【FZU - 1759】Super A^B mod C (数论,快速幂,快速乘,欧拉降幂,指数循环节,模板)
  5. (精)DEVC++的几个实用小技巧
  6. 【CodeForces - 1042B】Vitamins(去重方法,二进制或stlmap,水题)
  7. mysql数据库业务逻辑_Mysql业务设计(逻辑设计)
  8. 词法分析器c语言带注释,C语言词法分析器内容说明注释完整可运行代码.doc-资源下载在线文库www.lddoc.cn...
  9. linux依赖包在哪个目录,命令-Linux cmd在jar中搜索类文件,而与jar路径无关
  10. javascript特效_如何在网页添加鼠标点击特效