java丐帮_Java多线程学习笔记(一)
一、什么是多线程
首先是多线程的概念:
多线程是异步的,和单任务不同,并不一定按照代码的执行顺序(上图左)来运行,而是交错占用CPU运行(上图右);
二、如何使用多线程
JAVA多线程有两种实现方式:1、继承Thread类; 2、实现Runnable接口
其中实现Runnable接口是Java多线程的主要实现方法,因为JAVA的单继承特性,一旦继承了Thread类,就不能再继承别的类。而JAVA类可以继承多个接口。
1、继承Thread类实现方法:
public class Thread extendsThread {
@Overridepublic voidrun(){//super.run(); 调用父类的run方法
System.out.println("success!");
}
}public classRun {public static voidmain(String[] args) {
Thread a= newThread();
a.start();
System.out.println("end!");
}
}
其中 @Override 是JAVA注解,代码重写一个父类的函数,继承Thread类实现多线程,必须重写 run() 方法。
问题一:为什么要写super.run();既然是重写父类的 run() 方法为什么还要写 super.run() 呢?
首先是 Thread run()方法源码:
//Thread类重写了Runnable接口的run()方法。
//该run()方法首先判断当前是否有Runnable的实现target存在。 如果存在就执行target.run()
private Runnable target;
@Overridepublic voidrun() {if (target != null) {
target.run();
}
}
原来Thread类也是实现了Runnable接口;在run()方法中,首先会检查target是否为空,如果不是,则执行该target的run()方法。
首先上结论:
1、不管传入的Target是否为空,首先都会执行Thread自己的run()方法。如果重写了该方法且该方法中没有super.run(),那么是永远不会调用Runnable实现的run()方法;
2、如果没有重写该方法,则会去判断target是否为空,以此来决定调用target实现的run()方法;
3、如果重写了该方法,且该方法中有super.run(),在执行完该语句之前的所有代码后,会判断target是否为空,以此来决定调用target实现的run()方法
所以,super.run();正常情况下可以不写,但是我看到是书上都习惯性带上super.run() ,知道为什么的小伙伴非常感谢能够给我留言告诉我答案。
问题二:.start() 源码
/*JVM调用此线程的run方法。*/
public synchronized voidstart() {/*** 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 newIllegalThreadStateException();/*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*/}
}
}
另外,线程名.start() 的顺序,不代表线程的执行顺序!
run()方法只是一个普通方法,调用之后程序会等待run()方法执行完毕,所以是串行执行,而不是并行执行。
start()方法会启动一个线程,当线程得到CPU资源后会自动执行run()方法体中的内容,实现真正的并发执行。
2、实现Runnable接口的实现方法:
public class Thread_2 implementsRunnable{
@Overridepublic voidrun(){
System.out.println("i'm running!...");
}
}
实现原理和继承Thread类似,不再赘述。
3、实现Callable接口:
首先,定义Callable接口的实现类并实现call()方法:
importjava.util.Random;importjava.util.concurrent.Callable;public class MyThirdThread implements Callable{
@Overridepublic Integer call() throwsException {
Thread.sleep(6 * 1000);return newRandom().nextInt();
}
}
使用实现Callable接口的方式创建的线程,可以获取到线程执行的返回值、是否执行完成等信息。
Runnable和Callable的区别主要有以下几点:
Runable的执行方法是run(),Callable的执行方法是call()
call()方法可以抛出异常,run()方法如果有异常只能在内部消化
实现Runnable接口的线程没有返回值,实现Callable接口的线程能返回执行结果
实现Callable接口的线程,可以和FutureTask一起使用,获取到线程是否完成、线程是否取消、线程执行结果,也可以取消线程的执行。
java丐帮_Java多线程学习笔记(一)相关推荐
- java丐帮_java多线程学习笔记(三)
java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现"脏读"的现象,这个时候需要"临界区"的出现去解决多 ...
- java丐帮_java多线程学习笔记(五)
补充一个synchronized关键字的结论: 线程A先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法 A线程现持有object对 ...
- java丐帮_java多线程学习笔记(四)
上一节讲到Synchronized关键字,synchronized上锁的区域:对象锁=方法锁/类锁 本节补充介绍一下synchronized锁重入: 关键字synchronized拥有锁重入的功能,也 ...
- java丐帮_java多线程学习笔记(二)
上一节讲到多线程的创建,两种创建方式一种继承Thread类,一种实现Runnable接口: 常用的多线程函数: currentThread()方法 返回代码段正在被哪个线程调用的信息 i ...
- java丐帮_java多线程学习笔记(八)
本节开始线程间通信: 使用wait/notify实现线程间通信 生产者/消费者模式的实现 方法join的使用 ThreadLocal类的使用 可以通过使用 sleep() 结合 while(true) ...
- java丐帮_java多线程学习笔记(六)
本节开始synchronized关键字的最后一部分内容: 静态同步方法synchronized方法与synchronized(class)代码块 关键字synchronized还可以用在static静 ...
- java 编程思想 多线程学习笔记
java 编程思想 多线程学习笔记 一.如何创建多线程? 1.继承 java.lang.Thread 类 2.实现 java.lang.Runnable 接口 3.Callable接口 总之,在任何线 ...
- java线程集合点_Java多线程学习笔记(三) 甚欢篇
使人有乍交之欢,不若使其无久处之厌 <小窗幽记>很多时候,我们需要的都不是再多一个线程,我们需要的线程是许多个,我们需要让他们配合.同时我们还有一个愿望就是复用线程,就是将线程当做一个工人 ...
- java 指针_java多线程学习二十二:::java中的指针
在上面那个图,我们看到一个特殊的变量unsafe,它的包名是 sun.misc.Unsafe;从名字看,这个类应该是封装一些不安全的操作,为什么不安全?对c语言理解的朋友就知道了,指针是不安全的,在j ...
最新文章
- oracle xe 连接数据库,【Oracle XE系列之二】PLSQL Developer 远程连接Oracle XE数据库-Go语言中文社区...
- 学python编程-趣学Python编程
- python菜鸟教程h-python菜鸟教程,python好玩又简单的代码
- Spring Data ElasticSearch删除索引遇到的java.lang.IllegalStateException: Failed to load ApplicationContext异常
- 聚类(part3)--高级聚类算法
- yolo算法_不到2MB,超轻YOLO算法!准确率接近YOLOv3,速度快上45%
- PyQt5入门——删除、清空layout布局中的所有对象(含常见问题详解)
- mysql mybatis list循环_mybatis框架,使用foreach实现复杂结果的查询--循环List集合方式...
- 台式计算机睡眠了怎么唤醒,台式电脑睡眠了怎么唤醒
- 更适合Pythoner的标记语言Yaml学习总结
- 动手Lab|利用CSI和Kubernetes实现动态扩容
- python abc
- Python对象的比较、拷贝
- 沈是计算机专业考研分数线,计算机#2017年东北大学计算机考研究生分数线_计算机考研究生复试分数线...
- 度量 数据突变_使用K-Means和PCA进行基因组序列分析 COVID-19接下来如何突变?
- html设置字体 圆体,css font-family字体大合集
- C# winform中使窗体最小化(NotifyIcon)
- pillow软件 Android,Pillow自动睡眠追踪
- 【清澄】A1013. 进制转换4
- java面试题总结-详细分类