线程与进程

进程:

​ 是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应用程序可以同时运行多个进程;进程也是程序的一次执行过程,是系统运行程序的基本单位;系统运行一个程序即是一个进程从创建、运行到消亡的过程。

线程:

​ 进程内部的一个独立执行单元;一个进程可以同时并发地运行多个线程,可以理解为一个进程便相当于一个单 CPU 操作系统,而线程便是这个系统中运行的多个任务。

进程与线程的区别:

​ 进程:有独立的内存空间,进程中的数据存放空间(堆空间和栈空间)是独立的,至少有一个线程。

​ 线程:堆空间是共享的,栈空间是独立的,线程消耗的资源比进程小的多。

注意:

因为一个进程中的多个线程是并发运行的,那么从微观角度看也是有先后顺序的,哪个线程执行完全取决于CPU 的调度,程序员是不能完全控制的(可以设置线程优先级)。而这也就造成的多线程的随机性。

Java 程序的进程里面至少包含两个线程,主线程也就是 main()方法线程,另外一个是垃圾回收机制线程。每当使用 java 命令执行一个类时,实际上都会启动一个 JVM,每一个 JVM 实际上就是在操作系统中启动了一个线程,java 本身具备了垃圾的收集机制,所以在 Java 运行时至少会启动两个线程。

由于创建一个线程的开销比创建一个进程的开销小的多,那么我们在开发多任务运行的时候,通常考虑创建多线程,而不是创建多进程。

多线程

多线程技术可以更好地利用系统资源。主要优势在于充分利用了CPU的空闲时间片,用尽可能少的时间来对用户的要求做出响应,使得进程的整体运行效率得到较大提高,同时增强了应用程序的灵活性。

​ 更为重要的是,由于同一进程的所有线程共享同一内存,所以不需要特殊的数据传送机制,不需要建立共享存储区或共享文件,从而使得不同任务之间的协调操作与运行、数据的交互、资源的分配等问题更加易于解决。

创建多线程的五种方式

1.继承Thread类

Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。

启动线程的唯一方法就是通过Thread类的start()实例方法。

start()方法是Java的native方法,它将启动一个新线程,并执行run()方法。

这种方法实现多线程比较简单,通过自己创建的类直接继承Thread,并重写run()方法,就可以启动新线程并执行自己定义的run()方法。

优点:代码比较简单

缺点:该类无法继承其他类

1 public classThreadDemo1 {2

3 public static voidmain(String[] args) {4 ThreadDemo t1 = newThreadDemo();5 t1.setName("线程1");6 t1.start();7 ThreadDemo t2 = newThreadDemo();8 t2.setName("线程2");9 t2.start();10 }11

12 }13

14 class ThreadDemo extendsThread{15 @Override16 public voidrun() {17 for (int i = 1; i <= 10; i++) {18 System.out.println(Thread.currentThread().getName()+":"+i);19 }20 }21 }

2.实现Runnable接口

Java的继承属于单继承,如果一个类继承了其他的一个类就无法继承Thread类。但是一个类继承一个类的同时,可以实现多个接口。

优点:继承其他类,统一实现该接口的实例可以共享资源。

缺点:代码比较复杂。

1 public classThreadDemo2 {2

3 public static voidmain(String[] args) {4 MyThread myThread= newMyThread();5 Thread t1 = new Thread(myThread, "线程1");6 t1.start();7 Thread t2 = new Thread(myThread, "线程2");8 t2.start();9 }10

11 }12

13 class MyThread implementsRunnable{14 @Override15 public voidrun() {16 for (int i = 1; i <= 10; i++) {17 System.out.println(Thread.currentThread().getName()+":"+i);18 }19 }20 }

3.实现Callable接口

实现Callable接口和实现Runnable接口的方法基本相同,不过Callable接口中的call()方法有返回值,Runnable接口中的call()方法没有返回值。

1 public classThreadDemo3 {2

3 public static void main(String[] args) throwsExecutionException, InterruptedException {4 Callable myCallable = new MyCallable();5 //使用FutureTask类包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值

6 FutureTask futureTask = new FutureTask(myCallable);7 Thread t1 = new Thread(futureTask, "线程1");8 t1.start();9 System.out.println(futureTask.get());10 }11 }12

13

14 class MyCallable implements Callable{15

16 @Override17 public Object call() throwsException {18 for (int i = 1; i <= 10; i++) {19 System.out.println(i);20 }21 return Thread.currentThread().getName()+"执行完毕";22 }23 }

4.线程池

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

Executor类:提供了一系列工厂方法用于创建线程池,返回的线程池都实现了ExecutorService接口。

Java通过Executors提供四种线程池,分别为:

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

ExecutorService提供了sumbit()方法,传递一个Callable或Runnable,将线程放进线程池中,并执行。

优点:实现自动化装配,易于管理,循环利用资源。

1 public classThreadDemo4 {2

3 public static voidmain(String[] args) {4 ExecutorService pool = Executors.newFixedThreadPool(2);5 //将线程放入线程池中并执行

6 Future> submit = pool.submit(newMyRunnableThread());7 pool.submit(newMyRunnableThread());8 //关闭线程池

9 pool.shutdown();10 }11

12 }13

14 class MyRunnableThread implementsRunnable {15 @Override16 public voidrun() {17 for (int i = 1; i <=10 ; i++) {18 System.out.println(Thread.currentThread().getName()+":"+i);19 }20 }21 }

5.Timer类和TimerTask类

在这种实现方式中,Timer类实现的是类似定时任务的功能,也就是定时或者每隔一定时间触发一次线程。

Timer类本身实现的就是一个线程,只是这个线程是用来调用其他线程。

TimerTask类实现了Runnable接口,具备了多线程的能力。

在这种实现方式中,通过继承TimerTask使该类获得多线程的能力,重写run()方法,然后通过Timer类启动线程。

在实际使用时,一个Timer可以启动任意多个TimerTask实现的线程,但是多个线程之间会存在阻塞。所以如果多个线程之间如果需要完全独立运行的话,

最好还是一个Timer启动一个TimerTask实现。

1 public classThreadDemo5 {2

3 public static voidmain(String[] args) {4 Timer timer = newTimer();5 MyTimerTask myTimerTask1 = new MyTimerTask("线程1");6 MyTimerTask myTimerTask2 = new MyTimerTask("线程2");7 //启动线程

8 timer.schedule(myTimerTask1,0);9 timer.schedule(myTimerTask2,0);10 }11

12 }13

14 class MyTimerTask extendsTimerTask{15 privateString TimerTaskName;16

17 publicMyTimerTask(String TimerTaskName) {18 this.TimerTaskName=TimerTaskName;19 }20

21 @Override22 public voidrun() {23 for (int i = 1; i <=10 ; i++) {24 System.out.println(TimerTaskName+":"+i);25 }26 }27 }

简述java的线程_Java多线程的简述相关推荐

  1. java 优化线程_Java | 多线程调优(下):如何优化多线程上下文切换?

    通过上一讲的讲解,相信你对上下文切换已经有了一定的了解了.如果是单个线程,在 CPU 调用之后,那么它基本上是不会被调度出去的.如果可运行的线程数远大于 CPU 数量,那么操作系统最终会将某个正在运行 ...

  2. 简述java的线程_JAVA线程简述

    一.先谈谈并行与并发: 并行:是指两个或多个事件在同一时刻发生. 并发:是指连个或多个事件在同一时间间隔内发生. 二.接下来我们进入正题,讨论一下线程和进程: 1)什么是线程和进程? 进程:是一个具有 ...

  3. java thread 线程_Java Thread类简述

    今天我们来看下java.lang.Thread这个类. 在学习Thread类之前,先看下线程相关知识:线程的几种状态.上下文切换,然后介绍Thread类中的方法的具体使用. 1.线程的状态 线程从创建 ...

  4. java 查询线程_Java多线程查询

    嗨,我是并发编程领域的新手,我正在测试下面的代码,似乎while循环没有终止线程.有人可以帮助解释这里发生的事情. public class PrimePrinter{ public long cou ...

  5. java 容器 线程_JAVA多线程并发容器

    1.ArrayList线程不安全:CopyOnWriteArrayList线程安全 package concurrent; import java.util.ArrayList; import jav ...

  6. java终端线程_java多线程-中断线程

    大纲: java线程的中断原则 中断相关方法 中断实例 一.java线程中断原则 java中断是一种协作机制,每一个线程的中断都由线程自己处理,其他线程只是给要中断的线程一个中断标志. 二.相关方法 ...

  7. java 创建线程_java多线程|创建线程的各种方式

    javaDEMO 本网站记录了最全的各种JavaDEMO ,保证下载,复制就是可用的,包括基础的, 集合的, spring的, Mybatis的等等各种,助力你从菜鸟到大牛,记得收藏哦~~https: ...

  8. java 内部类 线程_java多线程基本概述(十四)——Thread内部类的几种写法

    importjava.util.concurrent.TimeUnit;//命名匿名类-Thread classInnerThread1 {private int countDown = 5;priv ...

  9. java tcp 线程_java 网络协议(一)Tcp多线程服务器端编程

    1,通用服务器代码: package multiThread; import java.io.IOException; import java.net.ServerSocket; import jav ...

最新文章

  1. php 锁的使用场景,抢购秒杀的场景使用锁个人认为不太合理?
  2. 利用redis实现分布式请求防重复提交
  3. hive集成spark和mysql
  4. java 调用tomcat api,调用servlet接口流程
  5. shell调用函数并获取函数返回值
  6. [转载]使用CPU时间戳进行高精度计时
  7. TIT 数据库实验一 在SQL Server中创建数据库(SQL入门教学一 从0到1)
  8. 计算机vb小游戏,用vb6.0做一个小游戏
  9. ADSL共享上网方式大总结(图)
  10. kitserver 6.33 完全简体中文版补丁
  11. matlab 图像傅里叶逆变换,用MATLAB实现图像的傅里叶变换.ppt
  12. php中根据数字月份返回月份的英文缩写
  13. vue实现换主题\皮肤功能
  14. android+警告声音,在Delphi XE5 / Android平台上播放声音警报/哔哔声
  15. 域控服务器导出证书,证书服务器(CA)的备份和还原
  16. hive的join,left join,right join,full outer join,left semi join,cross join
  17. 动态规划(Dynamic Programming, DP)简介
  18. Django2.0-表单(2)-表单的FIeld,验证器,提取错误字段
  19. 一个前端初学者的2018年终总结 | 掘金年度征文
  20. Arduino Nano 做的一个航模小遥控器

热门文章

  1. java 做项目踩坑,web项目踩坑过程
  2. linux免密登录_Linux SSH免密钥登录总结
  3. python安装pip_在MAC下安装pip,并关联到相应的python版本
  4. workbench出现“Unable to start the geometry editor”
  5. ArcGIS改变数据集或要素类的的坐标系(投影)
  6. 我的世界java刷怪数量_Minecraft我的世界Java版18w16a更新发布
  7. 广义典型相关分析_重复测量数据分析及结果详解(之二)——广义估计方程
  8. 第九节: EF的性能篇(二) 之 Z.EntityFramework.Extensions程序集解决EF的性能问题
  9. 1000并发 MySQL数据库_再送一波干货,测试2000线程并发下同时查询1000万条数据库表及索引优化...
  10. java s.charat_Java中s.charAt(index)用于提取字符串s中的特定字符操作