java并发编程之Thread类详细使用(四)
来源:互联网 发布:mac sierra重装系统 编辑:程序博客网 时间:2024/06/05 15:25
原博文地址:http://www.cnblogs.com/dolphin0520/p/3920357.html
1.线程的状态:new(创建)->runnable(就绪)->running(运行),运行时又分状态:阻塞(blocked),time waiting(睡眠或等待一定的事件),waiting(等待被唤醒)。
线程执行完毕,或者突然中断,进入dead(死亡or销毁)状态。如下图所示:
2.Thread之sleep()方法:
1)sleep相当于让线程睡眠,交出CPU,让CPU去执行其他的任务。
2)sleep方法不会释放锁,也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。
例子如下:
public class Threadsleep { private int i = 10; private Object object = new Object(); public static void main(String[] args) throws IOException { Threadsleep threadsleep = new Threadsleep(); //下面两个线程共享threadsleep对象 MyThread thread1 = threadsleep.new MyThread(); MyThread thread2 = threadsleep.new MyThread(); thread1.start(); thread2.start(); } class MyThread extends Thread{ @Override public void run() { synchronized (object) { i++; System.out.println("i:"+i); try { System.out.println("线程"+Thread.currentThread().getName()+"进入睡眠状态"); Thread.currentThread().sleep(10000); } catch (InterruptedException e) { // TODO: handle exception } System.out.println("线程"+Thread.currentThread().getName()+"睡眠结束"); i++; System.out.println("i:"+i); } } }}
结果:
结论:当Thread-0进入睡眠状态之后,Thread-1并没有去执行具体的任务。只有当Thread-0执行完之后,此时Thread-0释放了对象锁,Thread-1才开始执行。
3.Thread之join()方法:
join()join(long millis) //参数为毫秒join(long millis,int nanoseconds) //第一参数为毫秒,第二个参数为纳秒
1)假如在main线程中,调用thread.join方法,则main方法会等待thread线程执行完毕或者等待一定的时间。
2)如果调用的是无参join方法,则等待thread执行完毕,如果调用的是指定了时间参数的join方法,则等待一定的事件。
例子如下:
public class Threadjoin { public static void main(String[] args) throws IOException { System.out.println("进入线程"+Thread.currentThread().getName()); Threadjoin threadjoin = new Threadjoin(); MyThread thread1 = threadjoin.new MyThread(); thread1.start(); try { System.out.println("线程"+Thread.currentThread().getName()+"等待"); thread1.join(); System.out.println("线程"+Thread.currentThread().getName()+"继续执行"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } class MyThread extends Thread{ @Override public void run() { System.out.println("进入线程"+Thread.currentThread().getName()); try { Thread.currentThread().sleep(5000); } catch (InterruptedException e) { // TODO: handle exception } System.out.println("线程"+Thread.currentThread().getName()+"执行完毕"); } }}结果:
结论:1)当调用thread1.join()方法后,main线程会进入等待。然后等待thread1执行完之后再继续执行。
2)thread1.join()后让main线程进入阻塞状态,并且会释放线程占有的锁,并交出CPU执行权限。
4.Thread之interrupt方法:
1)interrupt,顾名思义,即中断的意思。
2)单独调用interrupt方法可以使得处于阻塞状态的线程抛出一个异常,也就说,它可以用来中断一个正处于阻塞状态的线程。
例子如下:
public class Threadinterrupt { public static void main(String[] args) throws IOException {Threadinterrupt threadinterrupt = new Threadinterrupt(); MyThread thread = threadinterrupt.new MyThread(); thread.start(); try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { } thread.interrupt(); } class MyThread extends Thread{ @Override public void run() { try { System.out.println("进入睡眠状态"); Thread.currentThread().sleep(10000); System.out.println("睡眠完毕"); } catch (InterruptedException e) { System.out.println("得到中断异常"); } System.out.println("run方法执行完毕"); } }}结果:
结论:1)interrupt方法可以中断处于阻塞状态的线程。
问题:interrupt能不能中断处于非阻塞状态的线程呢?如下例子:
public class Threadinterrupt2 { public static void main(String[] args) throws IOException {Threadinterrupt2 threadinterrupt2 = new Threadinterrupt2(); MyThread thread = threadinterrupt2.new MyThread(); thread.start(); try { Thread.currentThread().sleep(2000); } catch (InterruptedException e) { } thread.interrupt(); } class MyThread extends Thread{ @Override public void run() { int i = 0; while(i<Integer.MAX_VALUE){ System.out.println(i+" while循环"); i++; } } }}
结论:通过测试结果,发现直接调用interrupt方法不能中断正在运行中的线程。
问题:如何中断正在运行的线程呢?
1)一般会在MyThread类中增加一个属性 isStop来标志是否结束while循环,然后再在while循环中判断isStop的值。如下:
class MyThread extends Thread{ private volatile boolean isStop = false; @Override public void run() { int i = 0; while(!isStop){ i++; } } public void setStop(boolean stop){ this.isStop = stop; } }
那么就可以在外面通过调用setStop方法来终止while循环。
5.Thread其他方法:
1)getId 用来得到线程ID。
2)getName和setName。用来得到或者设置线程名称。
3)getPriority和setPriority。用来获取和设置线程优先级。
4)setDaemon和isDaemon。用来设置线程是否成为守护线程和判断线程是否是守护线程。
5)currentThread()。常用,用来获取当前线程。
演示关系图如下:
- java并发编程之Thread类详细使用(四)
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- Java并发编程:Thread类的使用
- MVP实现登录注册
- Python正则表达式
- springboot 解决跨域问题(options)
- 求1+2!+3!+...+20!的和
- kaggle中Titanic学到的知识
- java并发编程之Thread类详细使用(四)
- php+ajax 前台页面获取标准网络时间
- 在唯一密钥属性“name”设置为“aspNetCore”时,无法添加类型为“add”的重复集合项
- js json字符串转json 对象
- const用法
- 贪吃蛇
- hdu 3065 病毒侵袭持续中(AC自动机基本应用)
- java连接MySQL数据库
- 阿里云数据库全新功能Redis读写分离,全维度技术解析