java多线程-Thread
大纲
- sleep
- yield
- join
- setDaemon
- sleep:
public static native void sleep(long millis) throws InterruptedException;
sleep是本地静态方法。
sleep的作用是让线程进入TIME_WAITING状态,参数是多少毫秒。
class Test {
public static void main(String[] args){
Thread thread = new Thread(()->{
try {
Thread.sleep(2000);
System.out.println("over");
} catch (InterruptedException e) {
System.out.println("interrupt");
}
});
thread.start();
}
}
/**
结果:2秒后看到over
*/
sleep可被interrupt打断,抛出InterruptedException。
class Test {
public static void main(String[] args){
Thread thread = new Thread(()->{
try {
Thread.sleep(2000);
System.out.println("over");
} catch (InterruptedException e) {
System.out.println("interrupt");
}
});
thread.start();
thread.interrupt();
}
}
/**
结果:立刻看到interrupt
*/
注意:sleep方法并不释放锁。
- yield:
public static native void yield();
yield是一个本地静态方法。
yield表示当前线程申请交出执行权,但并不是一定会交出,依赖于系统的线程调度。
因此该方法并不稳定。
class Test {
public static void main(String[] args) throws InterruptedException {
TestYield t0 = new TestYield("thread0");
TestYield t1 = new TestYield("thread1");
t0.start();
t1.start();
}
}
class TestYield extends Thread {
public TestYield(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (Thread.currentThread().getName().equals("thread0")&&i==5) {
yield();
}
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
/**
结果:t0打印4后会交出执行权,一般不会连续打印thread0:4 thread0:5
*/
注意:yield 方法放弃执行权但并不释放锁。
- join:
之前看了一些博客说join就是把多线程变成单线程,其实并不是,执行join还是多线程。
class Test {
public static void main(String[] args) throws InterruptedException {
TestJoin t0 = new TestJoin();
TestJoin t1 = new TestJoin();
t0.start();
t1.start();
t0.join();
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
class TestJoin extends Thread{
@Override
public void run(){
for(int i=0;i<100;i++){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
/**
结果:t0.t1线程交替打印至t0执行结束,然后开始t1,main线程交替打印。
*/
结合源码看看join做了什么。
public final void join() throws InterruptedException {
join(0);
}
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
执行过程(这里讨论执行无参join方法,如果执行有参数join(xx),其实就是让main线程wait(xx)):
- main线程执行t0.join()。
- main线程执行join(),join()执行join(0),join(long millis)是一个同步方法。
- while(isAlive)这里的isAlive是t0的isAlive,如果t0存活,此时main线程持有t0的对象锁,执行wait。 (while确保了其他线程持有t0锁执行notifyAll后也无法唤醒main线程)
- main线程进入WAITING状态。
- t0,t1状态正常,交替执行至t0结束。
- t0结束后,由本地方法执行t0.notifyAll,main线程被唤醒。(源码中并看不到如何notifyAll的,线程结束后会执行一个本地方法notifyAll)
- 这时如果t1还没执行完成,main和t1交替执行。
https://blog.csdn.net/erica_1230/article/details/69388742 中介绍了:线程结束时调用的本地方法notifyAll
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
assert(threadObj.not_null(), "Java thread object must exist");
ObjectLocker lock(threadObj, thread);
thread->clear_pending_exception();
java_lang_Thread::set_stillborn(threadObj());
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
java_lang_Thread::set_thread(threadObj(), NULL);
lock.notify_all(thread);
thread->clear_pending_exception();
}
结论:当一个线程a执行线程b.join()则,线程a等待至线程b执行完毕后继续执行,这个过程并不影响其线程的执行。
- setDaemon
private boolean daemon = false;
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
- 线程的类型分为用户线程与守护线程,我们平时使用的一般是用户线程。
- 调用setDaemon(true)方法即可将线程设置问守护线程。注意isAlive方法判断该线程状态,因此setDaemon必须在线程start之前。
- 两者区别:用户线程运行结束,只剩下守护线程工作时虚拟机就会退出。所以说守护线程随时可能中断,而且随着用户线程消失而消失。
- 守护线程中创建的线程依然是守护线程。(源码中判断parent.isDaemon并把结果赋值给子线程)
java多线程-Thread的更多相关文章
- Java多线程Thread
转自:http://www.cnblogs.com/lwbqqyumidi/p/3804883.html Java总结篇系列:Java多线程(一) 多线程作为Java中很重要的一个知识点,在此还是 ...
- 探Java多线程Thread类和Runnable接口之间的联系
首先复习一下Java多线程实现机制,Java实现多线程方法有如下这么几种: 1.继承了(extends)Thread类 2.实现了(implements)Runnable接口 也就是说 有如下两种情 ...
- [Java多线程]-Thread和Runable源码解析
多线程:(百度百科借一波定义) 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提 ...
- Java多线程Thread类了解和使用
创建线程的两种方式 extends Thread 类 public class WelComeApp { public static void main(String[] args) { Welcom ...
- java 多线程--- Thread Runnable Executors
java 实现多线程的整理: Thread实现多线程的两种方式: (1)继承 Thread类,同时重载 run 方法: class PrimeThread extends Thread { long ...
- [java多线程] - Thread&Runnable运用
负载是一个很大的话题,也是一个非常重要的话题.不管是在大的互联网软件中,还是在一般的小型软件,都对负载有一定的要求,负载过高会导致服务器压力过大:负载过低又比较浪费服务器资源,而且当高请求的时候还可能 ...
- JAVA多线程Thread VS Runnable详解
要求 必备知识 本文要求基本了解JAVA编程知识. 开发环境 windows 7/EditPlus 演示地址 源文件 进程与线程 进程是程序在处理机中的一次运行.一个进程既包括其所要执行的指令,也 ...
- [Java多线程]-Thread和Runable源码解析之基本方法的运用实例
前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...
- java 多线程 Thread 锁ReentrantLock;Condition等待与通知;公平锁
1,介绍: import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; 在JA ...
随机推荐
- bootstrap列排序
<!DOCTYPE html> <html> <head> <title>Bootstrap 实例 - 列排序</title> <li ...
- Python基础-3
目录 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 知识插入:嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 一.函数基本语法 函数是什么? 函数一词 ...
- jquery数组拼接
var a=[]; var c=[80,90,70,100] var b={'张三':19,'成绩':c}; a.push(b); console.log("测试案例",a); 同 ...
- POJ1062 昂贵的聘礼(带限制的spfa)
Description 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为聘礼才答应把女儿嫁给他.探险家拿不出这么多金币,便请求酋长降低 ...
- java代码实现顺序队列
java实现顺序队列 package xianxinTable; import java.util.ArrayList; import java.util.Iterator; import com.s ...
- 使用VS Code开发C++
1. 参考/转载 vs code进行c/c++开发 VSCode 的第一个C++程序(windows)[更新2018.10.28] 2. C++开发相关插件(扩展商店中直接搜索) 至少要装C/C++. ...
- 「CF 600E」 Lomsat gelral
题目链接 戳我 \(Describe\) 给出一棵树,每个节点有一个颜色,求每个节点的子树中颜色数目最多的颜色的和. \(Solution\) 这道题为什么好多人都写的是启发式合并,表示我不会啊. 这 ...
- mysql 行转列,对列的分组求和,对行求和
CREATE TABLE students( id INT PRIMARY KEY, NAME VARCHAR(11)); CREATE TABLE courses( id INT PRIMARY K ...
- 20165219 《Java程序设计》实验一(Java开发环境的熟悉)实验报告
20165219 <Java程序设计>实验一(Java开发环境的熟悉)实验报告 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:王彦博 学号:20165219 成绩: 指 ...
- EF进阶篇(三)——上下文
前言 上下文,到底什么是上下文,且听我仔细吹来. 内容 在对EF实体进行关系操作的时候,第一步需要我们创建上下文实例对象,然后根据实体的变化进而通过上下文对该实体进行状态的修改,我的理解就是上下文就是 ...