java线程——Thread类的使用
2016-07-08 15:51
537 查看
线程和进程的概念
进程的概念:
进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
线程的概念:
线程是程序执行流的最小单元。线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。
线程的状态
线程包括以下这几个状态:创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、消亡(dead)。
当需要新起一个线程来执行某个子任务时,就创建了一个线程。但是线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源,在前面的JVM内存区域划分一篇博文中知道程序计数器、Java栈、本地方法栈都是线程私有的,所以需要为线程分配一定的内存空间),只有线程运行需要的所有条件满足了,才进入就绪状态。
当线程进入就绪状态后,不代表立刻就能获取CPU执行时间,也许此时CPU正在执行其他的事情,因此它要等待。当得到CPU执行时间之后,线程便真正进入运行状态。
线程在运行状态过程中,可能有多个原因导致当前线程不继续运行下去,比如用户主动让线程睡眠(睡眠一定的时间之后再重新执行)、用户主动让线程等待,或者被同步块给阻塞,此时就对应着多个状态:time waiting(睡眠或等待一定的事件)、waiting(等待被唤醒)、blocked(阻塞)。
当由于突然中断或者子任务执行完毕,线程就会被消亡。
多线程的实现方式
一种是继承Thread ,另外一种是实现Runnable接口。
Thread 有一些保存信息的属性,这些属性可以用来标示线程,显示线程的状态或者标示线程的优先级。
Id:线程的唯一标示
name:线程的名称
priority:线程的优先级
status:线程的状态
Thread常用的方法
①currentThread()方法
返回代码段正在被那个线程调用的信息。
main
②isAlive()方法
判断当前线程是否处于活动状态,活动状态就是线程已启动尚未终止。
结果:
begin=false
end=true
run=false
③sleep()方法
在指定的毫秒数内让正在执行的当前线程休眠。
begin
1467708456963
1467708457063
end
④getId()方法
取得线程的唯一标示。
1
⑤stop()方法
停止线程,这个方法是不安全的,已过时,不建议在使用,
......
9619
9620
9621
停止线程
⑥interrupted()或isInterrupted()
测试线程是否已经中断
两者的区别是interrupted 是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在A线程中去调用B线程对象的isInterrupted方法。)interrupted()会清除线程的中断状态,换句话说它会改变interrupted的值为false,如果连续两次调用该方法,第二次返回false;
打印结果:
线程开始
0
1
.........
408
第一次是否停止:false
409
.............
573
第二次是否停止:false
574
..........
第一次是否停止:true
第二次是否停止:true
⑦interrupt()
用于中断线程。调用该方法的线程的状态为将被置为"中断"状态
线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。我们通常用isInterrupted()去判断是否中断线程,如果为true,则中断
if(isInterrupted())
{
return
;
}
.............
Thread-0——>499720
是否停止——>false
Thread-0——>499719
Thread-0——>499718
...............
可以看出线程并没有停止
⑧suspend()和resume()
suspend()挂起线程,已过时,会造成死锁
resume()是线程重新回到可执行状态,已过时,配合suspend()使用
......
125541
当前时间戳------------------------1467962355695
当前时间戳------------------------1467962356695
125442
.........
⑨yield()
暂停当前正在执行的线程对象,并执行其他线程
结果:
6707毫秒
去掉下面一行的注释
结果:
8139毫秒
结果:
Thread-0:1毫秒
Thread-1:7毫秒
⑪setDaemon
将该线程标记为守护线程或用户线程。必须在启动线程前调用。
示例:
..............
28
29
main end!
可以看出main方法结束后就不在打印了
⑫join
打印结果:
-------子线程t1开始执行-----------
---------子线程t1结束执行----------
-------子线程t2开始执行-----------
---------子线程t2结束执行----------
-------子线程t3开始执行-----------
---------子线程t3结束执行----------
------主线程执行完毕----------
以上就是thread 常用的方法
进程的概念:
进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
线程的概念:
线程是程序执行流的最小单元。线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。
线程的状态
线程包括以下这几个状态:创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、消亡(dead)。
当需要新起一个线程来执行某个子任务时,就创建了一个线程。但是线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源,在前面的JVM内存区域划分一篇博文中知道程序计数器、Java栈、本地方法栈都是线程私有的,所以需要为线程分配一定的内存空间),只有线程运行需要的所有条件满足了,才进入就绪状态。
当线程进入就绪状态后,不代表立刻就能获取CPU执行时间,也许此时CPU正在执行其他的事情,因此它要等待。当得到CPU执行时间之后,线程便真正进入运行状态。
线程在运行状态过程中,可能有多个原因导致当前线程不继续运行下去,比如用户主动让线程睡眠(睡眠一定的时间之后再重新执行)、用户主动让线程等待,或者被同步块给阻塞,此时就对应着多个状态:time waiting(睡眠或等待一定的事件)、waiting(等待被唤醒)、blocked(阻塞)。
当由于突然中断或者子任务执行完毕,线程就会被消亡。
多线程的实现方式
一种是继承Thread ,另外一种是实现Runnable接口。
public class MyThread extends Thread{ @Override public void run() { // TODO Auto-generated method stub while(true) { System.out.println("fuck ........java"); } } }
Runnable run = new Runnable() { @Override public void run() { // TODO Auto-generated method stub while(true) { System.out.println("fuck...........java 1"); } } }; Thread t1 = new Thread(run); t1.start();
Thread 有一些保存信息的属性,这些属性可以用来标示线程,显示线程的状态或者标示线程的优先级。
Id:线程的唯一标示
name:线程的名称
priority:线程的优先级
status:线程的状态
Thread常用的方法
①currentThread()方法
返回代码段正在被那个线程调用的信息。
public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); }结果:
main
②isAlive()方法
判断当前线程是否处于活动状态,活动状态就是线程已启动尚未终止。
package com.test; public class MyThread extends Thread{ @Override public void run() { System.out.println("run="+this.isAlive()); } public static void main(String[] args) { MyThread t = new MyThread(); System.out.println("begin="+t.isAlive()); t.start(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("end="+t.isAlive()); } }
结果:
begin=false
end=true
run=false
③sleep()方法
在指定的毫秒数内让正在执行的当前线程休眠。
package com.test; public class MyThread extends Thread{ @Override public void run() { System.out.println("begin"); try { System.out.println(System.currentTimeMillis()); Thread.sleep(100); System.out.println(System.currentTimeMillis()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("end"); } public static void main(String[] args) { MyThread t = new MyThread(); t.start(); } }结果:
begin
1467708456963
1467708457063
end
④getId()方法
取得线程的唯一标示。
public static void main(String[] args) { Thread t = Thread.currentThread(); System.out.println(t.getId()); }结果:
1
⑤stop()方法
停止线程,这个方法是不安全的,已过时,不建议在使用,
package com.test; public class MyThread extends Thread{ private int i =0; @Override public void run() { while(true) { System.out.println(i++); } } public static void main(String[] args) { MyThread t = new MyThread(); System.out.println("线程开始"); t.start(); try { t.sleep(1); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t.stop(); System.out.println("停止线程"); } }结果:
......
9619
9620
9621
停止线程
⑥interrupted()或isInterrupted()
测试线程是否已经中断
两者的区别是interrupted 是作用于当前线程,isInterrupted 是作用于调用该方法的线程对象所对应的线程。(线程对象对应的线程不一定是当前运行的线程。例如我们可以在A线程中去调用B线程对象的isInterrupted方法。)interrupted()会清除线程的中断状态,换句话说它会改变interrupted的值为false,如果连续两次调用该方法,第二次返回false;
package com.test; public class MyThread extends Thread{ private int i =0; @Override public void run() { for(int i=0;i<500000;i++){ System.out.println(i); } } public static void main(String[] args) { MyThread t = new MyThread(); System.out.println("线程开始"); t.start(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t.interrupt(); System.out.println("第一次是否停止:"+t.interrupted()); System.out.println("第二次是否停止:"+t.interrupted()); } }
打印结果:
线程开始
0
1
.........
408
第一次是否停止:false
409
.............
573
第二次是否停止:false
574
..........
public static void main(String[] args) { MyThread t = new MyThread(); System.out.println("线程开始"); t.start(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t.interrupt(); System.out.println("第一次是否停止:"+t.isInterrupted()); System.out.println("第二次是否停止:"+t.isInterrupted()); }打印结果:
第一次是否停止:true
第二次是否停止:true
⑦interrupt()
用于中断线程。调用该方法的线程的状态为将被置为"中断"状态
线程中断仅仅是置线程的中断状态位,不会停止线程。需要用户自己去监视线程的状态为并做处理。我们通常用isInterrupted()去判断是否中断线程,如果为true,则中断
if(isInterrupted())
{
return
;
}
public class InterThread extends Thread{ @Override public void run() { // TODO Auto-generated method stub super.run(); for(int i=500000;i>0;i--){ System.out.println(Thread.currentThread().getName()+"——>"+i); } } public static void main(String[] args) { InterThread t = new InterThread(); t.start(); try { Thread.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t.interrupt(); System.out.println("是否停止——>"+t.interrupted()); t.stop(); } }输出结果:
.............
Thread-0——>499720
是否停止——>false
Thread-0——>499719
Thread-0——>499718
...............
可以看出线程并没有停止
⑧suspend()和resume()
suspend()挂起线程,已过时,会造成死锁
resume()是线程重新回到可执行状态,已过时,配合suspend()使用
package com.test; public class SRThread extends Thread{ @Override public void run() { // TODO Auto-generated method stub int i=0; super.run(); while(true) { System.out.println(i++); } } public static void main(String[] args) { SRThread t = new SRThread(); t.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t.suspend(); System.err.println("当前时间戳------------------------"+System.currentTimeMillis()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.err.println("当前时间戳------------------------"+System.currentTimeMillis()); t.resume(); } }结果:
......
125541
当前时间戳------------------------1467962355695
当前时间戳------------------------1467962356695
125442
.........
⑨yield()
暂停当前正在执行的线程对象,并执行其他线程
package com.test; import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; public class YeildTest extends Thread{ @Override public void run() { // TODO Auto-generated method stub long s = System.currentTimeMillis(); super.run(); for(int i=500000;i>0;i--){ //Thread.yield(); System.out.println(Thread.currentThread().getName()+"——>"+i); } long e = System.currentTimeMillis(); System.out.println((e-s)+"毫秒"); } public static void main(String[] args) { YeildTest yt = new YeildTest(); yt.start(); } }
结果:
6707毫秒
去掉下面一行的注释
//Thread.yield();
结果:
8139毫秒
⑩setPriority(int newPriority)
更改线程的优先级。优先级较高的线程得到CPU资源多,也就是CPU优先执行优先级高的线程。
public class YeildTest extends Thread{ @Override public void run() { // TODO Auto-generated method stub long s = System.currentTimeMillis(); super.run(); for(int i=500000;i>0;){ i--; } long e = System.currentTimeMillis(); System.out.println(getName()+":"+(e-s)+"毫秒"); } public static void main(String[] args) { YeildTest yt = new YeildTest(); yt.setPriority(10); yt.start(); YeildTest yt1 = new YeildTest(); yt1.setPriority(1); yt1.start(); } }
结果:
Thread-0:1毫秒
Thread-1:7毫秒
⑪setDaemon
将该线程标记为守护线程或用户线程。必须在启动线程前调用。
示例:
package com.sh; public class MyThread extends Thread{ private int i=0; @Override public void run() { while(true) { System.out.println(i++); try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { MyThread mt = new MyThread(); mt.setName("A"); mt.setDaemon(true); mt.start(); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("main end!"); } }打印结果:
..............
28
29
main end!
可以看出main方法结束后就不在打印了
⑫join
是用来指定当前主线程等待其他线程执行完毕后,再来继续执行Thread.join()后面的代码
package com.sun.test.join; /******************************************************************** join是用来指定当前主线程等待其他线程执行完毕后,再来继续执行Thread.join()后面的代码。 ***********************************************************************/ public class MyThread extends Thread{ @Override public void run() { // TODO Auto-generated method stub System.out.println("-------子线程"+Thread.currentThread().getName()+"开始执行-----------"); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("---------子线程"+Thread.currentThread().getName()+"结束执行----------"); } public static void main(String[] args) { MyThread myThread = new MyThread(); Thread t1 = new Thread(myThread,"t1"); t1.start(); try { t1.join(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Thread t2 = new Thread(myThread,"t2"); t2.start(); try { t2.join(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Thread t3 = new Thread(myThread,"t3"); t3.start(); try { t3.join(); } catch (InterruptedException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } System.out.println("------主线程执行完毕----------"); //结果线程执行顺序t1,t2,t3 } }
打印结果:
-------子线程t1开始执行-----------
---------子线程t1结束执行----------
-------子线程t2开始执行-----------
---------子线程t2结束执行----------
-------子线程t3开始执行-----------
---------子线程t3结束执行----------
------主线程执行完毕----------
以上就是thread 常用的方法
相关文章推荐
- java调用存储过程
- java 图片处理
- java自学篇之程序设计基础
- Java io操作,poi导出excel,集合自带排序,日志报告
- SpringMVC
- java 空指针
- Java环境搭建(JDK+MyEclipse+Maven+Resin)
- spark分类训练时因分类标签值太大导致outOfMemery
- java中接口回调与java回调机制
- Java SE基础知识点总结(三)
- JAVA NIO API简介
- Java实现ZIP解压功能
- SpringMVC使用@ResponseBody时返回json的日期格式、@DatetimeFormat使用注意
- java基础教程9:浏览java api
- java构造器的作用
- java中定义泛型类和定义泛型方法的写法
- java 集成 layIm 聊天工具
- Mybatis框架学习(四)—查询缓存与spring的整合开发
- spring事务详解
- java基础---->Comparable和Comparator的使用