多线程细节:

1. 面试题: sleep 方法 和 wait 方法异同点是什么?

相同点: 可以让线程 处于 冻结状态.

不同点:

1.
sleep 必须指定时间
wait 可以指定时间, 也可以不指定时间.

2.

sleep 时间到 线程会处于 临时阻塞 或者运行.

wait 如果没有指定时间 , 必须要通过 notify 或者 notifyAll 唤醒.

3.

sleep 不一定非要定义在 同步中.

wait 必须要定义在同步中. (锁)

4.

都定义在同步中,

线程执行到 sleep, 不会释放锁. (因为 sleep 肯定能醒)

线程执行到 wait, 会释放锁. (wait 就 不一定 能醒)

5.

方法名不相同

// *** 此时的同步代码块中 有多个线程, 不会 出现 线程安全 问题.

// *** 因为里面 的线程 光有执行权是不够的, 还得 需要锁.

synchronized(obj)
{
// sleep(5000); // *** 5000 毫秒, 也就是 5 秒. // *** 释放执行权,

wait(); // *** 0 1 2 // *** 线程池. 这三个 线程 一旦 被唤醒, 都会处于 临时阻塞 状态.

code...

}

synchronized(obj){

notifyAll(); // *** 3 // *** 持有锁.

code...

// *** 释放锁 对于同步代码块 而言 是 隐式的, 会在 同步代码块的最后 释放锁.
}

2. 线程 如何 停止呢?

stop 方法 过时了, 看其 描述发现, 有其它 解决方案.

线程结束: 就是让 线程任务代码 执行完, run 方法结束.

run 方法 咋结束呢?

run 方法中 通常都定义 循环, (如果没有定义循环 就不要 开启 多线程了, 没有意义.), 只要 控制循环 就 哦了.

*** 注意: 万一线程 在 任务中 处于了 冻结状态, 那么 它 还能去判断标记吗? 不能!

咋办? 答: *** 通过 查阅 stop 方法的描述, 发现提供了一个 解决方法, 如果目标线程 等待很长时间, 则 应使用 interrupt 方法来 中断等待.

所谓的 中断 并不是 停止线程.

*** interrupt 功能是 将线程 的 冻结状态 清除, 让线程 恢复到 运行状态(让 线程 重新 具备 CPU 的执行资格).

*** interrupt 让线程 从 冻结状态 恢复 回来. 清除 其 中断 状态.

*** 因为是 强制性的, 所以会有 异常发生, 可以在 catch 中 捕获异常, *** 在 异常处理中, 改变标记 让 循环结束, 让 run 方法结束.

3. 守护线程: 后台线程, 一般创建的 都是前台线程。

前台 后台 线程运行时 都是一样的, 获取 CPU 的执行权执行。

只有结束的时候有些不同。

前台线程要通过 run 方法结束, 线程结束。

后台线程 也可以通过 run 方法结束, 线程结束, 还有另一种情况,

当进程中 所有的前台线程都 结束了, 这时 无论后台线程 处于什么样的状态, 都会结束 , 从而 进程结束。

进程结束 依赖的 都是 前台线程。

之所以这里称之为 守护线程, 无非是 后台线程 在 守护着 前台线程。

前台 线程们结束了, 后台 线程 就自动跟着 结束了。

4. 线程 的 优先级: 是 用 数字标识的: 1-10

其中默认 初始优先级 是 5。 最明显的 三个 优先级 1, 5, 10

setPriority(10); // *** 设置线程 的优先级。

setPriority(Thread.MAX_PRIORITY);

setPriority(Thread.MIN_PRIORITY);

setPriority(Thread.NORM_PRIORITY);

5. 线程组: ThreadGroup: 可以通过 Thread 的 构造函数 明确 新 线程对象 所属的 线程组。

线程组的好处: 可以对 多个 同组的线程, 进行 统一的操作。

默认都属于 main 线程组。

6. 线程 是可以 自己 取名字的。

例如:

Thread t1 = new Thread(d,"旺财"); // *** 旺财 线程名

Thread t2 = new Thread(d,"小强"); // *** 小强 线程名

可以自己 给 线程 取名 以 增强 程序的 阅读性。

例如:

输入线程, 运行线程 etc.

7. join 方法

主线程执行到这里, 知道 t1 要加入 执行, 主线程 释放了 执行权、 执行资格 并处于 冻结状态, 什么时候恢复呢?

等 t1 线程 执行完。
try{t1.join();}catch(InterruptedException e){}

try{t1.join();}catch(InterruptedException e){} // *** 一般这个方法 用于 临时 加入一个 运算的线程, 让 该 线程 运算完, 程序才会继续执行。

8. yield(); (static 静态的)

// *** 暂停 当前正在 执行的线程对象, 并执行 其它 线程。

Thread.yield(); // *** 线程 临时暂停。 将执行权 释放, 让其他 线程 有机会 获取 执行权。

// *** 嵌套类 也就是 内部类。

9. 开发中, 线程 匿名内部类 体现。

// *** 面试题

new Thread(new Runnable() // *** 就是 往里面 传递了 一个 线程任务 对象。 在 执行的时候, 就按照 这个对象的 任务来执行。
{
public void run(){
}

}).start();

// *** 面试题

new Thread(new Runnable() // *** 就是 往里面 传递了 一个 线程任务对象。 在 执行的时候, 就按照 这个对象的 任务来执行。
{
public void run(){

System.out.println("runnable run");
}

}){

public void run(){

System.out.println("subthread run");
}

}.start();

}

 public class ThreadTest{

     public static void main(String[] args) {

     /*
// *** 使用 匿名内部类的方式 创建一个 线程。
new Thread(){ // *** 这是一个 Thread 的子类对象, 可以 进行 覆盖 run 方法的操作。 public void run(){ for(int x = 0; x < 40; x++){
System.out.println(Thread.currentThread().getName() +"....X...." + x);
}
} }.start(); Runnable r = new Runnable(){ public void run(){ for(int x = 0; x < 40; x++){
System.out.println(Thread.currentThread().getName() +"....Y...." + x);
} } }; new Thread(r).start(); for(int x = 0; x < 40; x++){
System.out.println(Thread.currentThread().getName() +"....Z...." + x);
} */ // *** 面试题 new Thread(new Runnable() // *** 就是 往里面 传递了 一个 线程任务对象。 在 执行的时候, 就按照 这个对象的 任务来执行。
{
public void run(){ System.out.println("runnable run");
} }){ public void run(){ System.out.println("subthread run"); // *** 执行
} }.start(); // new Thread 后面是一个 大括号, 就是一个 子类. }
//*** 子类 覆盖 父类, 运行的 时候 运行的 是 子类 方法. } /* class Thread{ private Runnable r;
Thread(Runnable r)
{ this.r = r; } public void run(){ if(r != null){ r.run(); // *** 这里调用的 是 Runnable 的 run 方法. } } public void start(){ run(); } } class SubThread extends Thread{ // *** 子类 覆盖 父类, 运行的 时候 运行的 是 子类 方法. public void run(){ System.out.pritnln("subthread run");
} } Runnable r = new Runnable();
{ public void run(){ System.out.println("runnable run"); } }
//Thread t = new Thread(r); SubThread t = new SubThread(r); t.start(); // *** 这里先 调用 start 方法, 然后 调用 run 方法, 然后 判断 r 不为空, 然后 调用 Runnable 的 run 方法(因为 传进去的 参数 是 Runnable 的 对象 r), 然后 输出 runnable run. */

关于 Java 中多线程的面试问题 详解的更多相关文章

  1. Java 中的异常和处理详解

    Java 中的异常和处理详解 原文出处: 代码钢琴家 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误 ...

  2. 关于Java中进程和线程的详解

    一.进程:是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命 周期.它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而 ...

  3. java中内存结构及堆栈详解

    一. java内存结构 1. Heap(堆):实例分配的地方,通过-Xms与-Xmx来设置 2. MethodArea(方法区域):类的信息及静态变量. 对应是Permanet Generation, ...

  4. Java中的异常和处理详解

    简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. ...

  5. JAVA中的String类(详解)

    Java.lang.String类是final类型的,因此不可以继承这个类.不能修改这个类.String是一个类不属于基本数据类型. 可以从源码中看到,String是一个final类型. String ...

  6. Java 中的异常和处理详解(转载)

    原文出处: 代码钢琴家 简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函 ...

  7. Java中的异常和处理详解(转发:https://www.cnblogs.com/lulipro/p/7504267.html)

    简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. ...

  8. 2018.8.1 Java中的反射和同步详解

    为何要使用同步? java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查), 将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他 ...

  9. java中ReentrantLock核心源码详解

    ReentrantLock简介 ReentrantLock是一个可重入且独占式的锁,它具有与使用synchronized监视器锁相同的基本行为和语义,但与synchronized关键字相比,它更灵活. ...

随机推荐

  1. Spring 中使用 @Scheduled 创建定时任务

    一.定时任务触发条件 1.在 Application 启动类上添加:@EnableScheduling 2.含定时方法的类上添加注解:@Component,该注解将定时任务类纳入 spring bea ...

  2. 一个企图用来进行前端交流的qq群

    我建了一个企图用来进行前端交流的qq群! 希望各位前端开发攻城狮们加入! 大佬.小白都欢迎! 禁广告党! 只是想有一个纯净的环境去讨论一下大家遇到的问题和行业前景之类的话题. 661270378 期待 ...

  3. 快学Scala 第十八课 (trait多继承)

    trait多继承: trait的继承并不像类拥有相同的含义!在下面这个例子中,如果还是运用类的继承的思想,那么运行结果将是什么也没有. trait Logged { def log(msg: Stri ...

  4. beego之操作model

    beego之操作model 1.环境配置 1>.下载安装orm go get github.com/astaxie/beego/orm 默认安装路径在gopath路径下,可使用go env查看路 ...

  5. 一步步剖析spring bean生命周期

    关于spring bean的生命周期,是深入学习spring的基础,也是难点,本篇文章将采用代码+图文结论的方式来阐述spring bean的生命周期,方便大家学习交流.  一  项目结构及源码 1. ...

  6. CRS-2674: Start of 'ora.cssd' on 'rac2' failed 引发的rac集群服务起不来问题

    问题背景:客户反馈Oracle rac集群节点宕机 1.首先查看宕机原因,归档日志满导致服务重启,查看归档日志路径是USE_DB_RECOVERY_FILE_DEST (默认路径), 安装的时候没有做 ...

  7. 由一次线上故障来理解下 TCP 三握、四挥 & Java 堆栈分析到源码的探秘

    本文导读: 生产故障场景介绍 TCP 建连三次握手过程 TCP 断连四次挥手过程 结合 Java 堆栈剖析源码 再从堆栈中找到"罪魁祸首" 问题优化方案总结 1.生产故障场景介绍 ...

  8. Kubernetes网络插件Flannel的三种工作模式

    跨主机通信的一个解决方案是Flannel,由CoreOS推出,支持3种实现:UDP.VXLAN.host-gw 一.UDP模式(性能差) 核心就是通过TUN设备flannel0实现(TUN设备是工作在 ...

  9. 我家很管事的猫——mycat初步部署实践与问题排查

    mycat,阿里出品的mysql中间件,提供读写分离和分库分表方案.项目中主要使用的是其读写分离功能. [如何部署?] 本文只采用并测试了双主从模式,配置看这一篇足矣: https://www.cnb ...

  10. 关于_GNU_SOURCE宏

    是在features.h中用于特性控制的一个功能测试宏 /user/include/features.h /* If _GNU_SOURCE was defined by the user, turn ...