【Java多线程系列二】Thread类的方法
Thread实现Runnable接口并实现了大量实用的方法。
/*
* 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机会,它自己也有可能再次得到执行机会
*/
public static native void yield(); /*
* 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将得到执行机会,在休眠时间结束后,当前线程继续执行
*/
public static native void sleep(long millis) throws InterruptedException; /*
* 一旦调用后宿主线程将阻塞,待当前线程结束后继续
*/
public final void join() throws InterruptedException; /*
* 一旦调用后宿主线程将阻塞,待当前线程结束后继续
*/
public final synchronized void join(long millis)throws InterruptedException; /*
* 中断线程
*/
public void interrupt(); /*
* on=true表示线程标记为守护线程(例如GC线程),若正在运行的所有线程都是守护线程,JVM将退出
*/
public final void setDaemon(boolean on);
Java代码:
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger; import org.junit.Assert;
import org.junit.Test; /**
* @Description: 测试Thread的方法
*/
public class ThreadMethodsTest { static String SLEEP = "sleep";
static String YIELD = "yield";
static String JOIN = "join"; private Map<String, ThreadMethodEnum> map = new ConcurrentHashMap<>(); class ThreadSleep implements Runnable {
private int millis; public ThreadSleep(int millis) {
this.millis = millis;
} @Override
public void run() {
System.out.println("Thread sleep run()...");
long threadId = Thread.currentThread().getId(); ThreadMethodEnum sleep = ThreadMethodEnum.SLEEP;
sleep.init(threadId); try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
sleep.stop();
map.put(sleep.getMethod(), sleep);
}
} class ThreadYield implements Runnable {
@Override
public void run() {
long threadId = Thread.currentThread().getId();
ThreadMethodEnum yield = ThreadMethodEnum.YIELD;
yield.init(threadId);
Thread.yield();
yield.stop();
map.put(yield.getMethod(), yield);
}
} class ThreadJoin implements Runnable {
private Thread thread;
private int millis = 0; public ThreadJoin(Thread thread) {
this.thread = thread;
} public ThreadJoin(Thread thread, int millis) {
this.thread = thread;
this.millis = millis;
} @Override
public void run() {
try {
System.out.println("Thread join run()...");
long threadId = Thread.currentThread().getId();
ThreadMethodEnum join = ThreadMethodEnum.JOIN;
join.init(threadId);
if (millis > 0) {
this.thread.join(millis);
} else {
this.thread.join();
}
join.stop();
map.put(join.getMethod(), join);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} final AtomicInteger interruptCount = new AtomicInteger(0);
final int interruptIndex = 100; class ThreadInterrupt extends Thread {
@Override
public void run() {
while (!isInterrupted()) {
interruptCount.incrementAndGet();
if (interruptCount.intValue() == interruptIndex) {
interrupt();
}
}
}
} @Test
public void testSleep() throws InterruptedException {
int millis = 1000;
Thread sleep = new Thread(new ThreadSleep(millis));
sleep.start();
sleep.join();
ThreadMethodEnum tme = map.get(SLEEP);
// 预期sleep时间与millis相近
Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 / millis));
} @Test
public void testYield() throws InterruptedException {
Thread yield = new Thread(new ThreadYield());
yield.start();
yield.join();
ThreadMethodEnum tme = map.get(YIELD);
// 预期yield消耗时间几乎为0
Assert.assertEquals(1, Math.round(tme.getStartTimeMillis() * 1.0 / tme.getStopTimeMillis()));
} @Test
public void testJoin() throws InterruptedException {
System.out.println("testJoin() ---- start----");
int millis = 1000;
Thread sleep = new Thread(new ThreadSleep(millis));
sleep.setName("Sleep Thread");
sleep.start();
Thread join = new Thread(new ThreadJoin(sleep));
join.setName("Join Thread");
join.start();
join.join();
ThreadMethodEnum tme = map.get(SLEEP);
// 预期sleep时间与millis相近
Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 / millis));
tme = map.get(JOIN);
// 预期join阻塞时间与millis相近
Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) * 1.0 / millis));
System.out.println("testJoin() ---- end----");
} @Test
public void testJoinMillis() throws InterruptedException {
System.out.println("testJoinMillis() ---- start----");
int millis = 500;
Thread sleep = new Thread(new ThreadSleep(millis * 2));
sleep.setName("Sleep Thread");
sleep.start();
Thread join = new Thread(new ThreadJoin(sleep, millis));
join.setName("Join Thread");
join.start();
join.join(); ThreadMethodEnum tme = map.get(SLEEP);
//预期sleep 不能在join阻塞结束前设置,固为null
Assert.assertTrue(tme == null); tme = map.get(JOIN);
//预期join阻塞时间与millis相近
Assert.assertEquals(1, Math.round((tme.getStopTimeMillis() - tme.getStartTimeMillis()) / millis));
System.out.println("testJoinMillis() ---- end----");
} @Test
public void testInterrupt() throws InterruptedException {
ThreadInterrupt interrupt = new ThreadInterrupt();
interrupt.start();
interrupt.join();
Assert.assertEquals(interruptIndex, interruptCount.intValue());
} } enum ThreadMethodEnum {
SLEEP(ThreadMethodsTest.SLEEP) {
@Override
public void init(long threadId) {
super.start(threadId);
}
},
YIELD(ThreadMethodsTest.YIELD) {
@Override
public void init(long threadId) {
super.start(threadId);
}
},
JOIN(ThreadMethodsTest.JOIN) {
@Override
public void init(long threadId) {
super.start(threadId);
}
}; private String method;
private long threadId;
private long startTimeMillis;
private long stopTimeMillis = 0; private ThreadMethodEnum(String method) {
this.method = method;
} public void stop() {
this.stopTimeMillis = System.currentTimeMillis();
} public String getMethod() {
return method;
} public long getThreadId() {
return threadId;
} public long getStartTimeMillis() {
return startTimeMillis;
} public long getStopTimeMillis() {
return stopTimeMillis;
} private void start(long threadId) {
this.threadId = threadId;
this.startTimeMillis = System.currentTimeMillis();
} public abstract void init(long threadId);
}
【Java多线程系列二】Thread类的方法的更多相关文章
- Java多线程系列二——Thread类的方法
Thread实现Runnable接口并实现了大量实用的方法 public static native void yield(); 此方法释放CPU,但并不释放已获得的锁,其它就绪的线程将可能得到执行机 ...
- java多线程系列(二)
对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...
- java多线程系列(二)---对象变量并发访问
对象变量的并发访问 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...
- java 多线程3:Thread类中的静态方法
Thread类中的静态方法 Thread类中的静态方法表示操作的线程是"正在执行静态方法所在的代码块的线程".为什么Thread类中要有静态方法,这样就能对CPU当前正在运行的线程 ...
- Java多线程原理及Thread类的使用
一.进程与线程的区别 1.进程是应用程序在内存总分配的空间.(正在运行中的程序) 2.线程是进程中负责程序执行的执行单元.执行路径. 3.一个进程中至少有一个线程在负责进程的运行. 4.一个进程中有多 ...
- (Java多线程系列二)线程间同步
Java多线程间同步 1.什么是线程安全 通过一个案例了解线程安全 案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果. 先来看一个线程不安全的例子 class Sell ...
- java多线程2:Thread中的方法
静态方法: Thread类中的静态方法表示操作的线程是"正在执行静态方法所在的代码块的线程". 为什么Thread类中要有静态方法,这样就能对CPU当前正在运行的线程进行操作.下面 ...
- Java多线程系列五——列表类
参考资料: http://xxgblog.com/2016/04/02/traverse-list-thread-safe/ 一些列表类及其特性 类 线程安全 Iterator 特性 说明 Vect ...
- Java多线程系列九——Atomic类
参考资料:https://fangjian0423.github.io/2016/03/16/java-AtomicInteger-analysis/http://www.cnblogs.com/54 ...
随机推荐
- Idea JAVA項目的导入JAR包和导出jar包
一.IDea项目中导入jar包 打开菜单project structure,然后选择modules/dependencies下选择右侧的+,选择jar包目录中的jar文件,导入 二.导出jar包 菜单 ...
- Nginx网络架构实战学习笔记(二):编译PHP并与nginx整合、安装ecshop、商城url重写实战
文章目录 编译PHP并与nginx整合 安装ecshop(这是一个多年前php的项目貌似,作为java开发的我暂时不去关心) 商城url重写实战 编译PHP并与nginx整合 安装mysql yum ...
- 全局配置一个ajax的错误监控
全局配置一个ajax的错误监控,比如$(document).ajaxError(function(evt, req, settings){ if(req && (req.stat ...
- EOJ 1058. 挤模具 (多边形面积)
题目链接:1058. 挤模具 题意 给出模具的底和体积,求模具的高. 思路 模具的底为多边形,因此求出多边形面积,用体积除以底的面积就是答案. 多边形的面积求解见 EOJ 1127. 多边形面积(计算 ...
- [已解决]报错:have mixed types. Specify dtype option on import or set low_memory=False
报错代码: import pandas as pd pd1 = pd.read_csv('D:/python34/program/wx_chat_single/qq_single.csv') 报错内容 ...
- 【linux】centos6/7 + nginx 利用certbot 申请https证书
没错我又踩坑了.昨晚上搞到十二点半才成功申请.鬼知道OJ服务器是个什么渣渣. 早上才算正式弄好,中间也学了不少东西,记录一下.这次是http转https,所以默认的还是只有80端口. 请务必确保自己的 ...
- proc伪文件系统 - 加载一个进程
内核模块的编译方法及注意事项 Ubuntu内核(2.6.32) 2.6内核中,模块的编译需要配置过的内核源码:编译.链接后生成的内核模块后缀为.ko:编译过程首先会到内核源码目录下读取顶层的Makef ...
- BUUCTF MISC部分题目wp
MISC这里是平台上比较简单的misc,都放在一起,难一些的会单独写1,二维码图片里藏了一个压缩包,用binwalk -e分离,提示密码为4个数字,fcrackzip -b -c1 -l 4 -u 得 ...
- Kali Linux 开启SSH
Kali Linux安装好默认是不开启ssh的,需要手工开启 1.修改/etc/ssh/sshd_config 配置文件: root@mykali:~# vi /etc/ssh/sshd_confi ...
- Linux账号管理与ALC权限设定(一)
UID 与 GID UID用户的编号 GID 用户群组的编号 账号登录时,有一个对应的文本来记录某个账户的UID与GID.然后获得这个UID去对应的密码文本中,取得密码进行比对,然后登陆. 保 ...