线程及与进程的区别

线程也被称为是轻量级的进程,是程序执行的最小单元。有四种状态:运行,就绪,挂起和结束。一个进程拥有多个线程,这些线程共享进程的一些资源如打开的文件,代码段,数据段和堆空间。

使用线程的优点在于:
1. 更好的交互性,GUI程序中可以将耗时操作单独一个线程,从而使程序具有更好的交互性。
2. 和进程相比,线程的开销更小,而且多线程在数据共享方面更加方便,效率更高
3. 多线程可以充分利用多CPU或者多核的并行执行能力
4. 多线程可以更好的简化程序的结构,使得程序更加利用理解和维护。将复杂任务的进程分解为多个线程

同步和异步

简单来说,同步存在等待,而异步不需要等待结果。因此为了实现同步,必须获得线程对象的锁,而其他想要同时获得该锁的对象只能等待,直到锁被释放。
实现同步可以利用同步代码块来实现也可以利用同步方法来实现。同步往往造成系统的瓶颈,所以尽量避免无谓的同步。

异步可以按非阻塞的思路来理解,例如每个线程都有运行时所需要的数据,在进行IO时可以不必等待其他线程的结果或者状态,也不必等待IO完毕之后才返回。

Java多线程实现的方式

主要有三种,继承Thread,实现Runnable,实现Callable
1. 继承Thread并重写run()方法:新建线程类之后,新建一个线程并调用其start()方法(该方法仅仅使线程变为就绪)。调用之后并不是立即执行的,而是等待OS的调度
2. 实现Runnable接口:常用的方法,和实现Thread类似,只是多了一步(将实现该Runnable接口的类作为Thread的参数实例化一个线程,剩下的和1一样)
3. 实现Callable接口重写call方法:Callable实际是Executor框架中的类,功能比Runnable强大。

实现Callable接口的功能体现在:
1. Callable接口的call方法在执行完成后会返回一个结果
2. call方法可以抛出异常
3. 通过Callable可以得到一个Future对象,Future是一个异步计算结果的对象,可以用来检查计算是否完成。

实例:

class MyThread1 extends Thread{public void run(){System.out.println("hello world 1");}}class MyThread2 implements Runnable{@Overridepublic void run() {System.out.println("hello world 2");}}class MyThread3 implements Callable<String>{@Overridepublic String call() throws Exception {return "hello world 3";}}public class hello {public static void main(String[]  args){// ThreadMyThread1 thread1 = new MyThread1();thread1.start();// RunnableMyThread2 thread2 = new MyThread2();Thread t = new Thread(thread2);t.start();// CallableExecutorService threadPool = Executors.newSingleThreadExecutor();Future<String> future = threadPool.submit(new MyThread3());try {System.out.println(future.get());} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}}

run()和start()

Thread类的对象既可以调用start()也可以调用run(),但是两者有本质的不同。如果仅仅是调用run()那么就和普通的成员方法调用是没有区别的,并不会开启多线程。而调用start()方法会异步的开启一个新的线程并等待被JVM调度执行,调度执行过程中会调用run()执行逻辑,run()执行完之后线程结束。

可以通过简单的例子验证,刚开始做多线程的时候总是分不清彼此

线程同步方法

Java提供了三种线程同步机制:
1. synchronize关键字:既可以修饰代码块也可以修饰方法。Java中每一个对象都有一个对象锁,在被synchronize修饰之后,如果想要执行同步代码块,就必须先获取该对象的对象锁。
2. wait()和notify():在同步代码块被执行期间,其他想获取同一个对象锁的线程可以调用wait()进入等待,并可以被notify()或者notifyAll()唤醒,然后去获取被释放的锁。
3. Lock接口和实现类ReentrantLock实现类:Lock提供了多种方法实现多线程的同步。 1)lock()阻塞方式获取锁,如果获取了锁就直接返回,否则等待直到获得;2)tryLock():非阻塞的方式获取锁,如果尝试获取成功,返回true否则返回false; 3)tryLock(long timeout, TimeUnit unit);给定时间内尝试获取锁,在指定时间之内获得就返回true否则超时false;4)lockInterruptibly():如果获取锁就立刻返回,如果没有那么线程状态变为休眠,直到获取锁或者当前线程被别的线程中断(也就是在lock的基础上加了中断唤醒)。

sleep()和wait()

两个方法都是将当前线程暂停执行一段时间的方法。区别如下:
1. 原理方面:sleep()是Thread的静态方法,是线程自身进行流程控制的方法,它会暂停本线程,把执行机会给其他线程,而且当睡眠时间到之后,自动唤醒。wait()属于是Object的方法。用于进程间同步或者通信,该方法使当前拥有该对象锁的线程等待,直到被notify或者notifyAll唤醒。
2. 对锁的处理方面:由于sleep只是暂停本线程执行,不涉及线程间的同步和通信,因此不会释放锁。而wait()调用后,调用线程就释放了锁,其他线程就可以执行同步代码块
3. 使用区域:sleep()就像一个特殊功能的方法,可以用在任何地方,而wait()是用于线程同步的,所以用在同步方法或者同步语句块中。

注意:
sleep()调用的时候必须捕获异常,因为可能会被interrpt()中断产生InterruptException;

补充:sleep()和yield()区别
1. sleep暂停线程之后,会把执行机会让给所有线程而不考虑优先级;yield只把执行机会给同优先级或者更高优先级的线程。
2. sleep会让当前线程进入阻塞状态,所以sleep()后的线程在指定时间内是不会执行的,而yield()只是使当前线程让步到可执行状态,因此可能被立刻调度执行
3. sleep()会抛出异常,而yield()不会,同时yield由于是和系统相关,所以移植性差一些

终止线程的方法

Java中终止线程的方法有stop()和suspend()。调用stop停止的时候,会释放所有的已经锁定的资源,使用stop的时候可能会造成不一致状态,导致程序不稳定;使用suspend由于不会释放锁,因此可能造成死锁。
一种安全的结束线程的方式就是让线程自然终止,结束run()的执行,线程就结束了。例如常用的重写run()时会在方法中写while(flag),那么可以通过其他线程修改该flag来控制该run的执行。如果需要被终止的线程当前是休眠状态,那么修改flag并没有什么用,那么可以通过interrut()中断唤醒,相应的run()中需要实现对该中断事件的捕获,然后执行结束逻辑。

【Java基础】多线程相关推荐

  1. java基础-多线程应用案例展示

    java基础-多线程应用案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.两只熊,100只蜜蜂,蜜蜂每次生产的蜂蜜量是1,罐子的容量是30,熊在罐子的蜂蜜量达到20的时候 ...

  2. 2020 - [Java基础 +多线程 + 虚拟机] + [计网 + 操作系统] + [MySQL] + [Redis] + [RocketMQ] + [Spring]常见面试题与解析

    前情提要:下面的内容主要由网上的资料和个人的理解整理而成.由于时间仓促可能没有给出相应的链接,并不代表我不尊重他人的劳动成果,后续更新会补上相应的链接.其中内容可能有理解不到位的地方,大家可选择性采纳 ...

  3. Java基础--多线程

    一.程序.进程.线程 1.区别 (1)程序是一段静态的代码,为应用程序执行的蓝本. (2)进程为程序的一次动态执行过程,包括代码的加载.执行以及执行完毕的一个完整过程. (3)线程是进程中的一个执行单 ...

  4. 黑马程序员——java基础---多线程(二)

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! -------  线程间的通信:简单来说,就是多个线程在操作同一资源,但操作的动作不同. 试想一下,对于同一个资 ...

  5. java基础------多线程(转)

    24.01_多线程(多线程的引入)(了解) 1.什么是线程 线程是程序执行的一条路径, 一个进程中可以包含多条线程 多线程并发执行可以提高程序的效率, 可以同时完成多项工作 2.多线程的应用场景 红蜘 ...

  6. 10 Java基础 多线程2

    /* 线程间通讯: 其实就是多个线程在操作同一个资源 但是操作的动作不同 */ class Res { Stringname; Stringsex; } class Input implements ...

  7. java基础—多线程

    1.Thread类 package com.wjl.base;public class MyThread extends Thread {/*** 利用继承的特点* 将线程名称传递 * @param ...

  8. 黑马程序员——Java基础---多线程

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 多线程 一.概述 说起多线程,我们就需要首先来谈谈什么叫做进程.所谓进程,就是在计算机上正在进行 ...

  9. Java基础---多线程宝典

    多线程 文章目录 多线程 核心概念 `Process`与`Thread` 线程三种创建方式 继承`Thread`类 使用多线程实现下载网络图片 实现`Runnable`接口 多线程同时操作同一个对象 ...

  10. 黑马程序员JAVA基础-多线程

    ------- android培训.java培训.期待与您交流! ---------- 线程: 线程是进程中的一个独立的控制单元 线程在控制着进程的执行 一个进程中至少有一个线程 线程的创建 第一种方 ...

最新文章

  1. 工业用微型计算机笔记(5)-指令系统(2)
  2. linux-ubuntu txt乱码
  3. android studio 自动生成sql语句,Android Studio Plugin 插件开发教程(三) —— 制作一个自动生成数据库代码的插件...
  4. 最近被安排搞搜索接口优化,压测了4次,才勉强达到要求~
  5. 旷视科技提出双向网络BiSeNet:实现实时语义分割
  6. 【李宏毅2020 ML/DL】P74 Generative Adversarial Network | Basic Idea
  7. --allow-file-access-from-files 命令的使用
  8. 肌电数据归一化并显示灰度图片
  9. 系统架构设计-企业信息化战略与实施 知识点
  10. 2007年“网络十大炒女”排行榜
  11. Excel如何快速查询银行卡开户行?
  12. guzzle php,PHP中使用Guzzle进行API测试
  13. 网站编辑企业如何应用智能员工节省了工资支出
  14. VB中传值(ByVal)和传地址(ByRef)的区别
  15. 为什么要处理子线程中的异常?不处理可以吗?那该如何处理?
  16. 推荐系统 --- 推荐算法 --- 基于用户行为的推荐算法 - 协同过滤算法
  17. postgres 源码解析25 缓冲池管理器-3
  18. 阿汤的疑惑(大数取余+质因数分解)
  19. R16 5G NR Two-Step RACH
  20. 中国传媒大学计算机学院期末考试题,2020中国传媒大学计算机技术考研专业课大纲、真题答题方法...

热门文章

  1. CMake编译cuda出错
  2. MFC创建属性表单“所需资源不存在”错误解决方法
  3. honey select 模型导出_道路建模-基本模型
  4. html模板引擎 字符串长度,Web前端模板引擎の字符串模板
  5. 自动化运维之CentOS7下PXE+Kickstart+DHCP+TFTP+HTTP无人值守安装系统
  6. andriod之log打印
  7. GNS3关联SecureCRT的配置。
  8. Oracle RAC 添加删除节点
  9. linux 下常见启动文件配置
  10. win 常用网络命令