网站首页 > java教程 正文
一、什么是线程和进程
在介绍什么是线程之前,有必要对进程进行了解下,在操作系统中线程是进程中的一个实体,线程并不会独立存在,进程是资源分配和调度的基本单位,一个进程中最少有一个线程,多个线程共享一个进程内的资源。
- 进程:程序运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源
- 线程:CPU调度的最小单位,必须依赖进程而存在。
二、什么是并发和并行
- 并行:指两个或多个事件在同一时间点发生。列如我们在学生时代,排队打饭,有多个窗口可以同时排队打饭。这就是并行。
- 并发:指单位时间内,处理事情的能力。列如我们在排队打饭时,单个窗口5分钟内可以处理10个人打饭,这就叫做并发。
三、什么是同步和异步
- 同步:所谓同步,就是发出一个功能调用时,在没有得到结果之前,该调用就不返回或继续执行后续操作。
- 异步:异步与同步相对,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作。当这个调用完成后,一般通过状态、通知和回调来通知调用者。对于异步调用,调用的返回并不受调用者控制。
四、如何学习好java并发编程
是不是总有一种感觉,在项目开发遇到问题时,打比方在了解一些并发工具类的使用时,会查阅相关资料,但过段时间又忘了,总感觉我已经学习了好多知识,但还是搞不懂,有时候好不容易解决这个问题,但又不知道这样做是不是对的或者是最优方案,那怎么样才能学习好并发编程? 其实在之前我也遇到过这样的问题,其实就2点,一个是从现象看本质,深入源码学习,二个是对整体并发工具类有个大体了解,最起码能知道有哪些工具类,在解决实际问题中,他们的优缺点是什么。有些人会问,那我已经知道这些并发工具类的使用用途,源码也看了,但他们为什么这样设计,这样设计有什么好处,我只能说这样的问题只有问并发编程大师Doug Lea了。附带一张java并发编程图谱
五、Java多线程并发三个核心问题:分工、同步和互斥
- 分工:列如在装修房屋时,装修公司的工作就是把房屋装修好,交接给客户进行验收,装修公司在安排任务时为了提高效率,安排木工负责打衣柜、橱柜,电工负责电线铺设等,通俗点讲就是安排不同的人做不同的事。在Java世界里,Java SDK 并发包里的 Executor、Fork/Join、Future本质上也是一种分工。
- 同步:不过是一个线程执行完了一个任务,如何通知执行后续任务的线程开工而已
- 互斥:所谓互斥,指的是同一时刻,只允许一个线程访问共享变量。
六、在JDK中已经明确说明了只有2中方式创建线程如下,第一种就是实现Runable接口的run方法、第二种就是继承Thread类重写run方法,另外一种大多数人可能会认为是第3种方式实现Callable接口,
There are two ways to create a new thread of execution. One is to
declare a class to be a subclass of <code>Thread</code>. This
subclass should override the <code>run</code> method of class
<code>Thread</code>. An instance of the subclass can then be
allocated and started. For example, a thread that computes primes
larger than a stated value could be written as follows:
1. 通过实现Runable接口,如下
public class RunableTest {
public static class RunableTask implements Runnable{
@Override
public void run() {
System.out.println("hello world");
}
}
public static void main(String[] args) {
RunableTask RunableTask = new RunableTask();
Thread thread = new Thread(RunableTask);
thread.start();
}
}
上述代码实现Runable接口的run方法,这样做的好处是RunableTask可以在继承其他类利于扩展,坏处是不能用this关键字获取当前线程相关信息,必须通过Thread.currentThread()方法来获取。
2. 通过继承Thread类,如下
public class ThreadTest extends Thread {
public static class ThreadTask extends Thread{
@Override
public void run() {
System.out.println("hello world");
}
}
public static void main(String[] args) {
ThreadTask threadTask = new ThreadTask();
threadTask.start();
}
}
- 上述代码创建一个ThreadTest类,在main函数中创建ThreadTest的实例,并调用start方法启动线程。注意当然调用start方法后,线程并没有马上执行,而是处于就绪状态,这个就绪状态指线程除了获取CPU资源外已经获取了其他资源,等待获取CPU资源后才真正是运行状态,当然运行完run方法后,线程终止结束。
- 继承的好处是可以在run方法中直接可以使用this关键字获取当前线程相关信息,而不用在使用Thread.currentThread()法,但坏处是,我们都知道java是单继承,这样做不利于扩展。
3. 通过实现Callable接口,如下
public class CallableTest {
public static class CallableTask implements Callable<String>{
@Override
public String call() {
return "hello world";
}
}
public static void main(String[] args) {
try {
CallableTask callableTask = new CallableTask();
FutureTask<String> futureTask = new FutureTask<>(callableTask);
new Thread(futureTask).start();
String res = futureTask.get();
System.out.println(res);
}catch (Exception e){
e.printStackTrace();
}
}
}
- 上述代码是通过FutureTask方式运行线程。
- 它比Runable和Thread的优点是它可以有返回值,缺点是在使用FutureTask的get方法获取返回值时它是阻塞的。
- call接口可以抛出异常,而Runable必须通过setUncaughtExceptionHandler()设置异常,才能在主线程中捕获到子线程的异常。
- 调用start方法后再次调用报IllegalThreadStateException异常,如下源码所示
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
/* Notify the group that this thread is about to be started
* so that it can be added to the group's list of threads
* and the group's unstarted count can be decremented. */
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
4. 他们3者关系如下
七、Java线程的生命周期
1. java线程的生命周期如下图所属(图片来源于网络和书籍)
- 如上图所式,线程有5中状态 新建状态(NEW)、就绪状态(RUNNABLE)、运行状态(RUNNING)、阻塞状态(BLOCKED)、死亡状态(DADE)
- NEW新建状态,是创建线程未启动状态
Java程序员福利:我把2019近一年经历过的Java岗位面试,和一些刷过的面试题都做成了PDF,PDF都是可以免费分享给大家的,关注私信我:【101】,免费领取!
猜你喜欢
- 2024-10-13 GitHub热点推荐!85W字并发编程图册(全彩版),竟是出自阿里
- 2024-10-13 「不得不看」Java并发编程一(java并发编程之美)
- 2024-10-13 深入理解java并发编程、并发编程相关概念基础篇
- 2024-10-13 Java 高并发编程详解:多线程与架构设计首稿写作完成
- 2024-10-13 Java面试专题——并发编程(juc并发编程面试题)
- 2024-10-13 Java编程——如何实现高效的并发控制
- 2024-10-13 Java线程与并发编程实践:深入理解volatile和final变量
- 2024-10-13 简单理解JAVA并发编程及高并发(java并发编程实战和并发编程的艺术)
- 2024-10-13 高并发编程系列:全面剖析Java并发编程之AQS的核心实现
- 2024-10-13 Java 多线程并发编程(关于java多线程并发控制机制)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)