线程基础知识01-Thread类,Runnable接口
常见面试题:创建一个线程的常用方法有哪些?Thread创建线程和Runnable创建线程有什么区别?
答案通常集中在,继承类和实现接口的差别上面;
如果深入问一些问题:1.要执行的任务写在run()方法中,为什么要用start()方法启动?等等问题
简单的问题还是可以回答一哈子,但是涉及到深入些的问题,就只能看看源码,才能更好的回答问题了:
1.为啥线程要用start()方法启动?
首先要从Thread类的源码入手:
- Thread类实现了Runnable接口
public
class Thread implements Runnable {
- 可以看出,Thread类里面有一个Runnable接口的元素,通过构造方法给Thread类里面的Runnable元素赋值;
private Runnable target;
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
//省略部分代码
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
//......省略部分代码
this.target = target;//注意这里的赋值操作
setPriority(priority);
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
- run方法很简单,就是判断是不是通过构造函数传入了Runnable接口,可以看出,线程的方法并没有执行;
@Override
public void run() {
if (target != null) {
target.run();
}
}
- start()方法中通过调用start0()执行Run()方法;类似于this.run();报错后也是忽略状态
public synchronized void start() {
if (threadStatus != 0)
throw new IllegalThreadStateException();
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 */
}
}
}
private native void start0();
- 可以借鉴的地方:
将任务封装在单独的接口中,可以多种实现,通过统一的方法去调用;
interface A {
run(){)
}
class B implements A {
private A a;
B(){}
B(A a){this.a = a}
run(){
if(a != null ){a.run}
}
start(){this.run()}
}
2.Thread的几种状态
- 类中给出的几种状态
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
下面这个图能更好的理解线程的状态
(图片来自《java并发编程艺术》)
1.线程开启,存在两种情况,运行状态和临时阻塞状态(调用方法,但没有获取到锁的情况下);
运行状态,具有执行资格和执行权;临时阻塞状态,只有执行资格没有执行权;
2.线程运行完之后有两种状态:冻结/等待和TERMINATED,
冻结状态释放执行权和执行资格。调用wait()或sleep()方法
3.interceptor和stop之间的区别
stop:终结一个线程不会保证资源释放,比较暴力;
interceptor:线程被中断了,可以通过isInterceptor方法获取是否被终端;但是抛异常,或者isItercepter方法后,终端状态会被清楚;
比较好的线程终止方案,可以增加一个标识符eg:flag=true的判断,要中断的时候,将标识符设置位false即可;
4.什么是自旋锁?什么是无锁编程?
CAS简单了解: https://www.cnblogs.com/perferect/p/12761558.html
5.死锁
死锁的定义:一组互相竞争资源的线程因互相等待,导致“永久”阻塞的现象。
最常出现死锁的情况是,当两个或多个锁互相嵌套,一个锁内部进行其他锁的竞争;
class test{
private static final Object obj1 = new Object();
private static final Object obj2 = new Obbject();
public static void main(String[] args){
new Thread(){
public void run(){
synchronized(obj1){
Thread.sleep(100);
synchronized(obj2){
Thread.sleep(200);
}
}
}
}.start();
new Thread(){
public void run(){
synchronized(obj2){
Thread.sleep(100);
synchronized(obj1){
Thread.sleep(200);
}
}
}
}.start();
}
}
线程基础知识01-Thread类,Runnable接口的更多相关文章
- JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)
实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...
- java 多线程:Thread类;Runnable接口
1,进程和线程的基本概念: 1.什么是进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机 ...
- Java多线程01(Thread类、线程创建、线程池)
Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于 ...
- java线程基础知识----线程基础知识
不知道从什么时候开始,学习知识变成了一个短期记忆的过程,总是容易忘记自己当初学懂的知识(fuck!),不知道是自己没有经常使用还是当初理解的不够深入.今天准备再对java的线程进行一下系统的学习,希望 ...
- Java并发之线程管理(线程基础知识)
因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...
- Java__线程---基础知识全面实战---坦克大战系列为例
今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的jav ...
- Java线程基础知识(状态、共享与协作)
1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...
- Java 线程--继承java.lang.Thread类实现线程
现实生活中的很多事情是同时进行的,Java中为了模拟这种状态,引入了线程机制.先来看线程的基本概念. 线程是指进程中的一个执行场景,也就是执行流程,进程和线程的区别: 1.每个进程是一个应用程序,都有 ...
- java线程基础知识----线程与锁
我们上一章已经谈到java线程的基础知识,我们学习了Thread的基础知识,今天我们开始学习java线程和锁. 1. 首先我们应该了解一下Object类的一些性质以其方法,首先我们知道Object类的 ...
随机推荐
- java实现第七届蓝桥杯打靶
打靶 题目描述 小明参加X星球的打靶比赛. 比赛使用电子感应计分系统.其中有一局,小明得了96分. 这局小明共打了6发子弹,没有脱靶. 但望远镜看过去,只有3个弹孔. 显然,有些子弹准确地穿过了前边的 ...
- PAT 害死人不偿命的(3n+1)猜想
卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把 ( 3n+1 )砍掉一半.这样一直反复砍下去,最后一定在某一步得到 n=1.卡拉兹在 195 ...
- mybatis源码解析-日志适配器
1.为什么需要使用适配器? 集成第三方日志组件,屏蔽日志组件底层实现,统一提供写日志的接口. 2.什么是适配器模式 定义:将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法 ...
- 面试官:换人!他连 TCP 这几个参数都不懂
每日一句英语学习,每天进步一点点: 前言 TCP 性能的提升不仅考察 TCP 的理论知识,还考察了对于操心系统提供的内核参数的理解与应用. TCP 协议是由操作系统实现,所以操作系统提供了不少调节 T ...
- 微信小程序生命周期,事件
目录 双线程模型 小程序中 app.js 中的生命周期 小程序的页面的生命周期 小程序的事件 双线程模型 像 Vue 的双向数据绑定 总结: 在渲染层将wxml文件与wxss文件转成js对象,也就是虚 ...
- SpringCloud之Security
Spring Security是Spring提供的一个安全框架,提供认证和授权功能,最主要的是它提供了简单的使用方式,同时又有很高的灵活性,简单,灵活,强大. 我个人博客系统采用的权限框架就是Spri ...
- 小技巧:如何用 Chrome 将 SVG 转成 PNG
怎么把 SVG 转成 PNG ?用 Chrome 吧,非常好用,还能设定自己想要的尺寸. 什么是 SVG ? SVG (Scalable Vector Graphics,可缩放矢量图形) 是基于 XM ...
- .Net Core微服务入门全纪录(二)——Consul-服务注册与发现(上)
前言 上一篇[.Net Core微服务入门全纪录(一)--项目搭建]讲到要做到服务的灵活伸缩,那么需要有一种机制来实现它,这个机制就是服务注册与发现.当然这也并不是必要的,如果你的服务实例很少,并且很 ...
- 如何在python列表中查找某个元素的索引
如何在python列表中查找某个元素的索引 2019-03-15 百度上回复别人的问题,几种方式的回答: 1) print('*'*15,'想找出里面有重复数据的索引值','*'*15) listA ...
- vsftpd服务器配置与使用
1.ftp简介 网络文件的共享主流的主要有三种,分别为ftp.nfs.samba ftp用于internet上的控制文件的双向传输 上传和下载的操作 下载 上传 将主机中的内容拷贝到计算机上 将文件从 ...