Java并发(一)——线程
文章目录
- 线程
- 1 进程和线程的区别
- 2 线程的创建方式
- 2.1 继承Thread类并重写run方法
- 2.2 实现Runnable接口
- 2.3 实现Callable接口
- 2.4 线程池
- 2.5 小结
- 3 线程的通知和等待
- 3.1 wait()函数
- 3.2 wait(long timeout)函数
- 3.3 notify()函数
- 3.4 notifyAll()函数
- 3.5 sleep()函数
- 3.6 yield()函数
- 3.7 join()函数
- 4 线程的中断
- 4.1 void interrupt()
- 4.2 boolean isInterrupted()
- 4.3 boolean interrupted()
- 5 线程状态
- 6 上下文切换
- 7 线程的优先级
- 8 线程组
- 9 守护线程与用户线程
线程
1 进程和线程的区别
进程时操作系统进行资源分配的基本单位,线程是CPU调度的基本单位
一个进程中有多个线程,多个线程共享堆和方法区,但是每个线程有自己的程序计数器和栈
程序计数器:用来记录线程当前要执行的指令地址,用于上下文切换时可以继续从之前的位置执行。如果执行的是native方法,则程序计数器为undefined
栈:用于存储该线程的局部变量
堆:进程中最大的一块内存,被所有线程共享,主要存放new操作创建的对象实例
方法区:用来存在JVM加载的类、常量以及静态变量等信息
在Java中,启动main函数就启动了一个JVM进程,而main函数所在的线程就是主线程
2 线程的创建方式
当创建完Thread对象后,该线程并没有被启动执行,直到调用start方法后才执行
调用start方法后,线程处于就绪状态,待获取CPU时间片后才真正开始运行
调用start()方法方可启动线程并使线程进入就绪状态,直接执行 run()方法的话不会以多线程的方式执行
2.1 继承Thread类并重写run方法
public static class MyThread extends Thread {private String name;public MyThread() {}public MyThread(String name) {this.name = name;}@Overridepublic void run() {System.out.println(name);}
}public static void main(String[] args) {Thread MyThread1 = new MyThread("name1");MyThread1.start();
}
2.2 实现Runnable接口
public static class MyRunnable implements Runnable {private String name;public MyRunnable() {}public MyRunnable(String name) {this.name = name;}@Overridepublic void run() {System.out.println(name);}
}public static void main(String[] args) {Runnable MyRunnable1 = new MyRunnable("hahah1");new Thread(MyRunnable1).start();
}
2.3 实现Callable接口
public static class MyCallable implements Callable<String> {@Overridepublic String call() throws Exception {return "123";}
}public static void main(String[] args) {FutureTask<String> futureTask = new FutureTask<>(new MyCallable());new Thread(futureTask).start();try {String res = futureTask.get();System.out.println(res);} catch (Exception e) {e.printStackTrace();}
}
2.4 线程池
2.5 小结
继承Thread的优势:在run方法内获取当前线程直接使用this
继承Thread的劣势:Java不支持多继承,继承Thread类就不能再继承其他的类。任务与代码没有分离,当多个线程执行一样的任务时需要多份任务代码?
实现Runnable的优势:可以多继承
实现Callable的优势:可以有返回值
3 线程的通知和等待
3.1 wait()函数
当线程调用了共享变量的wait()方法时,该线程阻塞,直到其他线程调用notify()或notifyAll(),或调用interrupt()中断
调用wait()函数,需要事先获取该共享变量的锁,否则会抛出IllegalMonitorStateException异常
执行wait()函数后,会释放已经获得的资源
虚假唤醒:一个线程可以从挂起状态转变为可运行状态,即使该线程没有被其他线程调用notify()或中断。为防止虚假唤醒,可以通过while循环不断判断是否满足唤醒条件,如果不满足则一直调用wait()
3.2 wait(long timeout)函数
线程在挂起后,超过timeout ms的时间,会自动返回
3.3 notify()函数
一个线程调用共享变量的notify()方法,会随机唤醒在该共享变量上调用过wait()方法挂起的一个线程
调用notify()函数,同样需要事先获取共享变量的锁,否则会抛出IllegalMonitorStateException异常
被唤醒的线程不一定会继续运行,因为该线程可能还需要获得共享变量的锁才能继续运行
3.4 notifyAll()函数
会唤醒在该共享变量上调用过wait()方法挂起的所有线程
3.5 sleep()函数
Thread类的静态方法,用于让线程睡眠,让出CPU时间片,不参与CPU调度,指定时间后返回处于就绪状态
但是该函数不会释放已经获得的资源
3.6 yield()函数
Thread类的静态方法,用于让线程交出CPU使用权,线程处于就绪状态,CPU重新调度线程的时候依旧有可能会调度到这个线程
该函数同样不会释放已经获得的资源
3.7 join()函数
该方法是Thread类提供的无参无返回值的方法
调用join()的线程,会阻塞,直到被调用join()方法的线程执行完毕后,该线程才会继续执行
用于多个线程加载资源,等待多个线程全部加载完毕再汇总处理
4 线程的中断
中断是一种线程间的协作模式,通过设置中断标志并不能直接中断线程,而是由被中断的线程自行决定
在wait()方法、sleep()、join()方法调用后,别的线程调用了该线程的interrupt(),则会抛出InterruptedException异常
4.1 void interrupt()
为某个线程设置中断标志位
4.2 boolean isInterrupted()
检测被调用线程是否被中断,是则返回true,否则返回false
4.3 boolean interrupted()
检测当前线程是否被中断,是则返回true,否则返回false,与上述不同的是,该方法会清除中断标志位
该方法是Thread类的静态方法,所以不管被调用的是哪个线程,获取的都是当前调用这个函数的线程是否中断
5 线程状态
new:初始状态。线程创建了,但是还未调用start方法启动线程
runnable:运行状态。包含操作系统中的就绪状态和运行状态,可能在运行,也可能在等待CPU调度
blocked:阻塞状态。线程正在等待锁的释放,进入同步块
waiting:等待状态。线程处于等待状态,等待其他线程唤醒。Object.wait()、Thread.join()、LockSupport.park()会使得线程进入等待状态
timed_waiting:超时等待状态。超过指定时间则自动唤醒
terminated:终止状态。线程执行完毕
线程状态转换图
6 上下文切换
线程在时间片内占用CPU执行任务,当时间片用尽则处于就绪状态让出CPU,从当前线程的上下文切换到了其他线程
切换线程上下文时需要保存当前线程执行的现场,再次执行到该线程时恢复现场
7 线程的优先级
Java中线程优先级范围是1-10,默认优先级为5。优先级只是给系统一个参考值,线程最终在操作系统的优先级还是由操作系统决定
thread1.setPriority(10)
8 线程组
Java中用ThreadGroup来表示线程组,如果创建线程时没有明确指定,则使用父线程的线程组作为自己的线程组
线程组统一异常处理
public class ThreadGroupDemo {public static void main(String[] args) {ThreadGroup threadGroup1 = new ThreadGroup("group1") {// 继承ThreadGroup并重新定义以下方法// 在线程成员抛出unchecked exception// 会执行此方法public void uncaughtException(Thread t, Throwable e) {System.out.println(t.getName() + ": " + e.getMessage());}};// 这个线程是threadGroup1的一员Thread thread1 = new Thread(threadGroup1, new Runnable() {public void run() {// 抛出unchecked异常throw new RuntimeException("测试异常");}});thread1.start();}
}
9 守护线程与用户线程
Java中线程分为:daemon线程(守护线程)和user线程(用户线程)
守护线程是否结束,并不影响JVM的退出,当非守护线程都结束时,JVM会退出
thread.setDaemon(true);
main线程运行结束后,JVM会自动创建一个DestroyJavaJVM的线程,等待所有用户线程结束后终止JVM
Java并发(一)——线程相关推荐
- Java 并发编程 -- 线程池源码实战
一.概述 小编在网上看了好多的关于线程池原理.源码分析相关的文章,但是说实话,没有一篇让我觉得读完之后豁然开朗,完完全全的明白线程池,要么写的太简单,只写了一点皮毛,要么就是是晦涩难懂,看完之后几乎都 ...
- Java并发编程——线程池的使用
在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...
- Java并发编程—线程间协作方式wait()、notify()、notifyAll()和Condition
原文作者:Matrix海 子 原文地址:Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 目录 一.wait().notify()和notifyA ...
- java workerdone_【架构】Java并发编程——线程池的使用
前言 如果我们要使用线程的时候就去创建一个,这样虽然非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为 ...
- Java并发教程–线程池
Java 1.5中提供的最通用的并发增强功能之一是引入了可自定义的线程池. 这些线程池使您可以对诸如线程数,线程重用,调度和线程构造之类的东西进行大量控制. 让我们回顾一下. 首先,线程池. 让我们直 ...
- Java并发编程-线程安全基础
线程安全基础 1.线程安全问题 2.账户取款案例 3.同步代码块synchronized synchronized的理解 java中有三大变量的线程安全问题 在实例方法上使用synchronized ...
- 灵魂发问,Java并发和线程池,只言片语真的可以讲清楚吗?
线程池 最近看到线程池,被里边乱七八槽的参数给搞晕了,你能不能给我讲讲呀? 对于从事后端开发的同学来说,线程是必须要使用了,因为使用它可以提升系统的性能.但是,创建线程和销毁线程都是比较耗时的操作,频 ...
- 灵魂发问!Java并发和线程池,只言片语真的可以讲清楚吗?
线程池 最近看到线程池,被里边乱七八槽的参数给搞晕了,你能不能给我讲讲呀? 对于从事后端开发的同学来说,线程是必须要使用了,因为使用它可以提升系统的性能.但是,创建线程和销毁线程都是比较耗时的操作,频 ...
- Java并发编程—线程同步类
原文作者:洲洋1984 原文地址:Java 并发包中的高级同步工具 Java 中的并发包指的是 java.util.concurrent(简称 JUC)包和其子包下的类和接口,它为 Java 的并发提 ...
- Java 并发总结——线程池
一.线程池 在程序启动的时候就创建若干线程来响应处理,它们被称为线程池,里面的线程叫工作线程 (1)线程池的作用 1.降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. 2.提高响应 ...
最新文章
- 腾讯告诉你小孩子的钱也有多好赚,一月花费25万不是梦!
- Django中六个常用的自定义装饰器
- 时频分析:短时傅立叶变换实现(5)
- mysql 数据库学习(触发器)
- Matrix-tree 定理的一些整理
- 欧拉回路 欧拉路径
- mysql合集_Mysql数据库知识点合集
- composer安装
- 摄影测量学之共线方程的应用
- Debian 配置Bind9 DNS服务器
- ADC前端电压跟随器和ADC相关参数之---分辨率和精度(INL和DNL)
- H.265编码原理入门
- JetChat-简仿微信聊天应用
- matlab图上面加箭头,利用matlab如何在图形中绘制箭头
- 论文阅读笔记《Siamese Convolutional Neural Network for Camera Pose Estimation and Visual Servoing》
- 如何使文章分栏脚注不分栏?
- html5抓鱼游戏,小班捉小鱼游戏教案
- 如何让电脑运行速度变快
- django-外键和表关系
- 【通知】关于SRRC认证无线电发射设备型号核准的通知