大纲

  1. sleep
  2. yield
  3. join
  4. 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)):

  1. main线程执行t0.join()。
  2. main线程执行join(),join()执行join(0),join(long millis)是一个同步方法。
  3. while(isAlive)这里的isAlive是t0的isAlive,如果t0存活,此时main线程持有t0的对象锁,执行wait。 (while确保了其他线程持有t0锁执行notifyAll后也无法唤醒main线程)
  4. main线程进入WAITING状态。
  5. t0,t1状态正常,交替执行至t0结束。
  6. t0结束后,由本地方法执行t0.notifyAll,main线程被唤醒。(源码中并看不到如何notifyAll的,线程结束后会执行一个本地方法notifyAll)
  7. 这时如果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;
}
  1. 线程的类型分为用户线程与守护线程,我们平时使用的一般是用户线程。
  2. 调用setDaemon(true)方法即可将线程设置问守护线程。注意isAlive方法判断该线程状态,因此setDaemon必须在线程start之前。
  3. 两者区别:用户线程运行结束,只剩下守护线程工作时虚拟机就会退出。所以说守护线程随时可能中断,而且随着用户线程消失而消失。
  4. 守护线程中创建的线程依然是守护线程。(源码中判断parent.isDaemon并把结果赋值给子线程)

java多线程-Thread的更多相关文章

  1. Java多线程Thread

    转自:http://www.cnblogs.com/lwbqqyumidi/p/3804883.html Java总结篇系列:Java多线程(一)   多线程作为Java中很重要的一个知识点,在此还是 ...

  2. 探Java多线程Thread类和Runnable接口之间的联系

    首先复习一下Java多线程实现机制,Java实现多线程方法有如下这么几种: 1.继承了(extends)Thread类 2.实现了(implements)Runnable接口 也就是说  有如下两种情 ...

  3. [Java多线程]-Thread和Runable源码解析

    多线程:(百度百科借一波定义) 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提 ...

  4. Java多线程Thread类了解和使用

    创建线程的两种方式 extends Thread 类 public class WelComeApp { public static void main(String[] args) { Welcom ...

  5. java 多线程--- Thread Runnable Executors

    java 实现多线程的整理: Thread实现多线程的两种方式: (1)继承 Thread类,同时重载 run 方法: class PrimeThread extends Thread { long ...

  6. [java多线程] - Thread&Runnable运用

    负载是一个很大的话题,也是一个非常重要的话题.不管是在大的互联网软件中,还是在一般的小型软件,都对负载有一定的要求,负载过高会导致服务器压力过大:负载过低又比较浪费服务器资源,而且当高请求的时候还可能 ...

  7. JAVA多线程Thread VS Runnable详解

    要求 必备知识 本文要求基本了解JAVA编程知识. 开发环境 windows 7/EditPlus 演示地址 源文件   进程与线程 进程是程序在处理机中的一次运行.一个进程既包括其所要执行的指令,也 ...

  8. [Java多线程]-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  9. java 多线程 Thread 锁ReentrantLock;Condition等待与通知;公平锁

    1,介绍: import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;   在JA ...

随机推荐

  1. (转)15个非常棒的jQuery无限滚动插件【瀑布流效果】

    原文地址:http://www.cnblogs.com/lyw0301/archive/2013/06/19/3145084.html 现在,最热门的网站分页趋势之一是jQuery的无限滚动(也即瀑布 ...

  2. JAVA自动装箱拆箱与常量池

    java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...

  3. Springcloud踩坑记---使用feignclient远程调用服务404

    公司项目进行微服务改造,由之前的dubbo改用SpringCloud,微服务之间通过FeignClient进行调用,今天在测试的时候,eureka注册中心有相应的服务,但feignclient就是无法 ...

  4. 标准库函数begin和end------c++primer

    尽管能计算得到尾后指针,但这种用法极易出错.为了让指针的使用更简单.更安全,c++新标准引入了两个名为begin和end的函数.这两个函数与容器中的两个同名成员功能类似,不过数组毕竟不是类类型,因此这 ...

  5. sqlite数据库文件查看

  6. OC 术语表

    术语表 本附录包含了很多会用到的非正式定义术语.有些术语与Obective-C语言有关,其他术语则有自己的语源,来自面向对象程序设计的规范.在后一种情况中,术语的含义只有明确应用于Obective-C ...

  7. node.js安装以及git 的使用说明

     第一步:安装node.js: Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.   Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高 ...

  8. 基于 Django 的手机管理系统

    前段时间和小组一起完成数据库作业,觉得收获挺多的,分享到博客来. 一.概述 打算通过设计数据库,然后结合 Python 框架Django,实现在网页上对数据库的增删改查(本例以手机的管理为例,不考虑订 ...

  9. Python3之shutil模块

    一. 简介 shutil 是高级的文件,文件夹,压缩包处理模块. 二. 使用 shutil.copyfileobj(fsrc, fdst[, length])将文件内容拷贝到另一个文件中 import ...

  10. JDBC_ResultSet结果集用法_游标原理_关闭连接问题

    依次关闭使用对象及连接 ResultSet---Statement--Connectionimport java.sql.Connection;import java.sql.DriverManage ...