一、什么是多线程

首先是多线程的概念:

多线程是异步的,和单任务不同,并不一定按照代码的执行顺序(上图左)来运行,而是交错占用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多线程学习笔记(一)相关推荐

  1. java丐帮_java多线程学习笔记(三)

    java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现"脏读"的现象,这个时候需要"临界区"的出现去解决多 ...

  2. java丐帮_java多线程学习笔记(五)

    补充一个synchronized关键字的结论: 线程A先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法 A线程现持有object对 ...

  3. java丐帮_java多线程学习笔记(四)

    上一节讲到Synchronized关键字,synchronized上锁的区域:对象锁=方法锁/类锁 本节补充介绍一下synchronized锁重入: 关键字synchronized拥有锁重入的功能,也 ...

  4. java丐帮_java多线程学习笔记(二)

    上一节讲到多线程的创建,两种创建方式一种继承Thread类,一种实现Runnable接口: 常用的多线程函数: currentThread()方法        返回代码段正在被哪个线程调用的信息 i ...

  5. java丐帮_java多线程学习笔记(八)

    本节开始线程间通信: 使用wait/notify实现线程间通信 生产者/消费者模式的实现 方法join的使用 ThreadLocal类的使用 可以通过使用 sleep() 结合 while(true) ...

  6. java丐帮_java多线程学习笔记(六)

    本节开始synchronized关键字的最后一部分内容: 静态同步方法synchronized方法与synchronized(class)代码块 关键字synchronized还可以用在static静 ...

  7. java 编程思想 多线程学习笔记

    java 编程思想 多线程学习笔记 一.如何创建多线程? 1.继承 java.lang.Thread 类 2.实现 java.lang.Runnable 接口 3.Callable接口 总之,在任何线 ...

  8. java线程集合点_Java多线程学习笔记(三) 甚欢篇

    使人有乍交之欢,不若使其无久处之厌 <小窗幽记>很多时候,我们需要的都不是再多一个线程,我们需要的线程是许多个,我们需要让他们配合.同时我们还有一个愿望就是复用线程,就是将线程当做一个工人 ...

  9. java 指针_java多线程学习二十二:::java中的指针

    在上面那个图,我们看到一个特殊的变量unsafe,它的包名是 sun.misc.Unsafe;从名字看,这个类应该是封装一些不安全的操作,为什么不安全?对c语言理解的朋友就知道了,指针是不安全的,在j ...

最新文章

  1. oracle xe 连接数据库,【Oracle XE系列之二】PLSQL Developer 远程连接Oracle XE数据库-Go语言中文社区...
  2. 学python编程-趣学Python编程
  3. python菜鸟教程h-python菜鸟教程,python好玩又简单的代码
  4. Spring Data ElasticSearch删除索引遇到的java.lang.IllegalStateException: Failed to load ApplicationContext异常
  5. 聚类(part3)--高级聚类算法
  6. yolo算法_不到2MB,超轻YOLO算法!准确率接近YOLOv3,速度快上45%
  7. PyQt5入门——删除、清空layout布局中的所有对象(含常见问题详解)
  8. mysql mybatis list循环_mybatis框架,使用foreach实现复杂结果的查询--循环List集合方式...
  9. 台式计算机睡眠了怎么唤醒,台式电脑睡眠了怎么唤醒
  10. 更适合Pythoner的标记语言Yaml学习总结
  11. 动手Lab|利用CSI和Kubernetes实现动态扩容
  12. python abc
  13. Python对象的比较、拷贝
  14. 沈是计算机专业考研分数线,计算机#2017年东北大学计算机考研究生分数线_计算机考研究生复试分数线...
  15. 度量 数据突变_使用K-Means和PCA进行基因组序列分析 COVID-19接下来如何突变?
  16. html设置字体 圆体,css font-family字体大合集
  17. C# winform中使窗体最小化(NotifyIcon)
  18. pillow软件 Android,Pillow自动睡眠追踪
  19. 【清澄】A1013. 进制转换4
  20. java面试题总结-详细分类

热门文章

  1. 条款20 宁以pass-by-reference-to-const替换pass-by-value
  2. macOS开发入门教程 : Part 2
  3. 2022李宏毅机器学习hw1--COVID-19 Cases Prediction
  4. og标签对SEO的作用及用法
  5. 在C++中响铃的两种方法
  6. OpenStreetMap初探(七)——渲染和地图瓦片之安装Mapnik
  7. Android6.0动态获取摄像头权限(举一反三)
  8. 测试工程师简历编写指南
  9. 用Python写了一个水果忍者小游戏
  10. SaaSBase:艺赛旗iS-RPA是什么?