java多线程Thread的实现方法代码详解
作者:中华雪碧 发布时间:2022-01-03 01:02:28
之前有简单介绍过java多线程的使用,已经Thread类和Runnable类,为了更好地理解多线程,本文就Thread进行详细的分析。
start()
我们先来看看API中对于该方法的介绍:
使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
结果是两个线程并发地运行;当前线程(从调用返回给 start 方法)和另一个线程(执行其 run 方法)。
多次启动一个线程是非法的。特别是当线程已经结束执行后,不能再重新启动。
用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的 start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
start方法是开启线程的方法,使用后java会创建一个新的线程执行run里的方法。这是一个小demo:
for(int i=0;i<3;i++){
Thread t= new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" end");
}
});
t.start();
}
System.out.println("it is over");
执行结果:
it is over
Thread-1 start
Thread-0 start
Thread-2 start
Thread-0 end
Thread-1 end
Thread-2 end
由于多线程是有随机性的,所以每次的结果可能都不一样,这一点也是我们需要注意的,线程的执行顺序和调用顺序并不一致。
run()
run方法就是调用Thread设置的Runnable的run方法,将上面的demo进行修改:
for(int i=0;i<3;i++){
Thread t= new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" end");
}
});
t.run();
}
System.out.println("it is over");
执行结果:
main start
main end
main start
main end
main start
main end
it is over
run方法的直接结果和start有很大的差别,完全是按顺序执行,并没有开启新线程。
stop()
stop方法是强制停止线程的执行,是非安全的,不要使用此方法。在调用stop时, 会对锁定的资源进行释放,但这种释放是非一致的,容易引起程序问题。如果想要控制线程的停止,可以使用自定义变量来判断或者isInterrupted()方法:
class Thread1 extends Thread {
@Override
public void run() {
//判断线程体是否运行
while (!isInterrupted()) {
// Do Something
}
}
}
interrupt()
interrupt的作用是通知线程,你已经被中断的,但具体的中断执行需要在线程自定义处理,甚至你可以不理会继续执行。具体的中孤单是会线程执行join、wait、sleep方法时,抛出InterruptedException。
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" start");
try {
for(int i=0;i<100000;i++){
System.out.println(i+"");
Thread.sleep(1);
}
} catch (InterruptedException e) {
System.out.println("the thread is interrupted");//可以在这里做资源释放,日志记录等
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" end");
}
});
t1.start();
Thread.sleep(100);
t1.interrupt();
执行结果:
65
66
67
68
the thread is interrupted
java.lang.InterruptedException: sleep interrupted
Thread-0 end
at java.lang.Thread.sleep(Native Method)
at com.wk.aqi.act.Test$1.run(Test.java:23)
at java.lang.Thread.run(Thread.java:745)
isInterrupted()
判断线程是否中断,在执行上面的interrupt方法后,会return true。
setPriority(int newPriority)和getPriority()
设置线程的优先级和获取线程的优先级,cpu分配的资源给侧重给priority高的线程。
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
long t = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+" start");
for(int i=0;i<1000;i++){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" t1 end "+(System.currentTimeMillis()-t));
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
long t = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+" start");
for(int i=0;i<1000;i++){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" t2 end "+(System.currentTimeMillis()-t));
}
});
t1.setPriority(10);
t2.setPriority(1);
t2.start();
t1.start();
执行结果:
Thread-0 start
Thread-1 start
Thread-0 t1 end 1357
Thread-1 t2 end 1371
在优先级一样的情况下,t1和t2是几乎同时完成的,在优先级不一样的情况,有明显的差别。
getName()
比较简单,获取线程的名称。
join()和join(long millis)
jion方法的作用是等待线程执行完成,join(long millis)可以设置最长等待时间。比如主线程需要等待子线程完成,获取子线程的结果后才能继续往下执行,这时候就可以使用join方法
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
long t = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName()+" start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" t1 end "+(System.currentTimeMillis()-t));
}
});
t1.start();
t1.join();
System.out.println("等待t1执行完,再执行");
执行结果:
Thread-0 start
Thread-0 t1 end 1001
等待t1执行完,再执行
来源:https://segmentfault.com/a/1190000012213171


猜你喜欢
- ActivityManager.RunningAppProcessInfo类与获取正在运行的应用程序每一个应用程序都会运行在它独立的进程里,
- 本文实例讲述了C#使用foreach语句遍历二维数组的方法。分享给大家供大家参考。具体分析如下:如果通过for语句循环遍历二维数组需要两重循
- 本文实例总结了Android开发之资源文件用法。分享给大家供大家参考,具体如下:这里记录在Android开发中经常用到的一些用法arrays
- 学习spring依赖注入的时候碰到这个坑,折腾了许久,记录一下以防其他小伙伴入坑!该异常主要原因是因为JDK与Spring版本不一致。要么更
- Android 判断SIM卡属于哪个移动运营商第一种方法:获取手机的IMSI码,并判断是中国移动\中国联通\中国电信TelephonyMan
- Android 滑动返回Activity的实现代码近来玩微信的时候偶然发现,向左滑动朋友圈竟然可以返回主页,故引起兴趣特研究代码很简洁pac
- 1、引例class Complex{private: double Real,Image;public: &nbs
- 如下所示:public class Test{public static void main(String[] args) {
- private void txtBarCode_KeyPress(object sender, KeyPressEventArg
- 什么是断点续传用户上传大文件,网络差点的需要历时数小时,万一线路中断,不具备断点续传的服务器就只能从头重传,而断点续传就是,允许用户从上传断
- 一、简介地图控件自v2.3.5版本起,支持多实例,即开发者可以在一个页面中建立多个地图对象,并且针对这些对象分别操作且不会产生相互干扰。文件
- Java序列化是将一个对象编码成一个字节流,反序列化将字节流编码转换成一个对象。 序列化是
- 通过自定义view实现仿iOS实现滑动两端的点选择时间的效果效果图自定义的view代码public class Ring_Slide2 ex
- 简介Quartz是一款功能强大的任务调度器,可以实现较为复杂的调度功能,如每月一号执行、每天凌晨执行、每周五执行等等,还支持分布式调度。本文
- 1.简单介绍一下NDK和JNINDK:NDK是Native Development Kit的缩写,是Google提供的一套工具集
- 目录开始准备开始动画画圆弧项目使用背景图完整代码今天介绍一个很简单的倒计时动画,仿酷狗音乐的启动页倒计时效果,也是大多数APP在用的一个动画
- 在日常工作中,我们有时会需要修改字体的颜色来突出文本重点,让读者更容易抓住文章要点。在今天这篇文章中,我将为大家介绍如何以编程方式,在Wor
- 本文以一个简单的实例为大家介绍Android编程的入门知识,该案例是属于较早期的实例程序,读者可以对比学习,全面的了解Android程序的演
- 现如今的APP各式各样,同样也带来了各种需求,一个下拉刷新都能玩出花样了,前两天订饭的时候不经意间看到了“百度外卖”的下拉刷新,今天的主题就
- 一、背景在我们编写程序的过程中,程序中可能随时发生各种异常,那么我们如何优雅的处理各种异常呢?二、需求1、拦截系统中部分异常,返回自定义的响