常见面试题:创建一个线程的常用方法有哪些?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接口的更多相关文章

  1. JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)

    实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...

  2. java 多线程:Thread类;Runnable接口

    1,进程和线程的基本概念: 1.什么是进程: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机 ...

  3. Java多线程01(Thread类、线程创建、线程池)

    Java多线程(Thread类.线程创建.线程池) 第一章 多线程 1.1 多线程介绍 1.1.1 基本概念 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于 ...

  4. java线程基础知识----线程基础知识

    不知道从什么时候开始,学习知识变成了一个短期记忆的过程,总是容易忘记自己当初学懂的知识(fuck!),不知道是自己没有经常使用还是当初理解的不够深入.今天准备再对java的线程进行一下系统的学习,希望 ...

  5. Java并发之线程管理(线程基础知识)

    因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...

  6. Java__线程---基础知识全面实战---坦克大战系列为例

    今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的jav ...

  7. Java线程基础知识(状态、共享与协作)

    1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...

  8. Java 线程--继承java.lang.Thread类实现线程

    现实生活中的很多事情是同时进行的,Java中为了模拟这种状态,引入了线程机制.先来看线程的基本概念. 线程是指进程中的一个执行场景,也就是执行流程,进程和线程的区别: 1.每个进程是一个应用程序,都有 ...

  9. java线程基础知识----线程与锁

    我们上一章已经谈到java线程的基础知识,我们学习了Thread的基础知识,今天我们开始学习java线程和锁. 1. 首先我们应该了解一下Object类的一些性质以其方法,首先我们知道Object类的 ...

随机推荐

  1. 【asp.net core 系列】4. 更高更强的路由

    0. 前言 在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转.那么,我们回过头来,再看看路由的一些其他用法. 1. 路由属性(Route Attribute) 按照英文的直接翻译, ...

  2. CGLIB动态代理机制,各个方面都有写到

    CGLIB库介绍 代理提供了一个可扩展的机制来控制被代理对象的访问,其实说白了就是在对象访问的时候加了一层封装.JDK从1.3版本起就提供了一个动态代理,它使用起来非常简单,但是有个明显的缺点:需要目 ...

  3. maven配置阿里云仓库进行下载

    maven阿里云仓库下载 为了解决maven在下载jar包的时候,速度比较慢的问题,可以配置阿里云仓库配置方式的进行下载,首先找到您安装的maven路径. 在conf文件夹下面有个settings.x ...

  4. 曹工说JDK源码(1)--ConcurrentHashMap,扩容前大家同在一个哈希桶,为啥扩容后,你去新数组的高位,我只能去低位?

    如何计算,一对key/value应该放在哪个哈希桶 大家都知道,hashmap底层是数组+链表(不讨论红黑树的情况),其中,这个数组,我们一般叫做哈希桶,大家如果去看jdk的源码,会发现里面有一些变量 ...

  5. MySQL 8.0权限认证(上)

    MySQL 8.0授权认证   一.系统权限表   user 存放用户账户信息以及全局级别(所有数据库)权限,决定了来自哪些主机的哪些用户可以访问数据库实例,如果有全局权限则意味着对所有数据库都有此权 ...

  6. arduino 的analogRead() 和analogWrite()

    模拟输入analogRead()函数的返回值范围是0 到1023; 而模拟输出analogWrite()函数的输出值范围是0 到255; 所以: val = analogRead(potpin); / ...

  7. phpstorm 安装 YUI Compressor 实 结合现自动压缩文件

    YUI compressor 官方: http://yui.github.io/yuicompressor/ 下载的快速入口: https://github.com/yui/yuicompressor ...

  8. 关于Api的那些事儿!

    工作中一直在写Api数据接口,但大部分的Api都存在这样的问题 1.接口请求的地址和参数暴露 2.重要接口返回数据明文暴露 3.APP登录态请求的数据完全性问题 4.代码层的数据完全性问题(从代码层有 ...

  9. c# 不同单例的不同意义

    前言 在c#,可能有很多五花八门的单例给你选择,分什么懒汉模式等等什么模式,其实不同的写法对程序是有一定影响的. 正文 为什么需要单例呢?其实我们自己是可以控制单例的,只是单例模式给了我们一个好的设计 ...

  10. PyQt中QThread多线程的正确用法【待完善】

    先贴几篇有意思的讨论 https://www.qt.io/blog/2010/06/17/youre-doing-it-wrong#commento-login-box-container https ...