并发编程(5)Thread类的使用(sleep/yield/join)
2016-03-15 16:32
543 查看
Thread类中的方法:
.1)sleep
强制当前正在执行的线程休眠指定的时间(线程转到阻塞状态),让出CPU给其他线程,在此期间,sleep不会释放对象锁,当休眠时间到期,恢复到可运行状态。关于sleep不会释放对象锁,请看下面例子:
.2)yield
调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。它跟sleep方法类似,同样不会释放锁。但是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程(也包括当前线程)有获取CPU执行时间的机会。
注意:调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。
.3)join
在一个线程里面调用另一个线程的join方法时,表示本线程阻塞直到另一个线程执行完毕。
主要用途:多个线程并行执行,如果某一个线程要用到一个或者多个线程的执行结果,或者某个线程必须等待一个或者多个线程执行完毕方能执行,可以采用join方法。
请看下面例子:
实际上 join()方法调用的事wait方法,这个可以从源码得知,
由于wait方法会让线程释放对象锁,所以join方法同样会让线程释放对一个对象持有的锁。
参考资料:
http://www.cnblogs.com/dolphin0520/p/3920357.html
.1)sleep
强制当前正在执行的线程休眠指定的时间(线程转到阻塞状态),让出CPU给其他线程,在此期间,sleep不会释放对象锁,当休眠时间到期,恢复到可运行状态。关于sleep不会释放对象锁,请看下面例子:
public class TestSleep2 { private int i = 10; private Object object = new Object(); public static void main(String[] args) throws IOException { TestSleep2 test = new TestSleep2(); MyThread thread1 = test.new MyThread(); MyThread thread2 = test.new MyThread(); thread1.start(); thread2.start(); } class MyThread extends Thread{ @SuppressWarnings("static-access") @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); } } } }
i:11 线程Thread-0进入睡眠状态 线程Thread-0睡眠结束 i:12 i:13 线程Thread-1进入睡眠状态 线程Thread-1睡眠结束 i:14从上面输出结果可以看出,当Thread-0进入睡眠状态之后,Thread-1并没有去执行具体的任务。只有当Thread-0执行完之后,此时Thread-0释放了对象锁,Thread-1才开始执行
.2)yield
调用yield方法会让当前线程交出CPU权限,让CPU去执行其他的线程。它跟sleep方法类似,同样不会释放锁。但是yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程(也包括当前线程)有获取CPU执行时间的机会。
注意:调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。
public class TestYield extends Thread{ @SuppressWarnings("static-access") @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println("当前正在执行线程:"+Thread.currentThread().getName()+",i="+i); Thread.currentThread().yield(); } } public static void main(String[] args) { TestYield t1=new TestYield(); TestYield t2=new TestYield(); TestYield t3=new TestYield(); t1.start(); t2.start(); t3.start(); }输出结果:
当前正在执行线程:Thread-0,i=0 当前正在执行线程:Thread-2,i=0 当前正在执行线程:Thread-1,i=0 当前正在执行线程:Thread-2,i=1 当前正在执行线程:Thread-0,i=1 当前正在执行线程:Thread-2,i=2 当前正在执行线程:Thread-1,i=1 当前正在执行线程:Thread-1,i=2 当前正在执行线程:Thread-0,i=2当然,每次执行结果可能不一样,从上面可以看出,当前线程调用yield()方法之后,有可能执行其他线程,也有可能当前线程继续获取CPU权限。
.3)join
在一个线程里面调用另一个线程的join方法时,表示本线程阻塞直到另一个线程执行完毕。
主要用途:多个线程并行执行,如果某一个线程要用到一个或者多个线程的执行结果,或者某个线程必须等待一个或者多个线程执行完毕方能执行,可以采用join方法。
请看下面例子:
public class TestJoin { private int count=0; class Thread1 extends Thread{ @SuppressWarnings("static-access") public void run(){ while(count<100){ count++; if(count==10){ try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } System.out.println("now Count-size :"+count); } } class Thread2 extends Thread{ public void run(){ System.out.println("count-size:"+count); } } public static void main(String[] args) throws InterruptedException { TestJoin t= new TestJoin(); Thread1 t1=t.new Thread1(); Thread2 t2=t.new Thread2(); t1.start(); //t1.join(); t2.start(); } }当注释掉t1.join();时,结果如下:
count-size:10 now Count-size :100启用t1.join()时,结果如下:
now Count-size :100 count-size:100可以看出没有调用t1.join()方法时,t2在t1进入休眠时已经执行完毕,调用了该方法时,t2等待t1执行完才开始执行。
实际上 join()方法调用的事wait方法,这个可以从源码得知,
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; } } }wait方法会让线程进入阻塞状态,并且会释放线程占有的锁,并交出CPU执行权限。
由于wait方法会让线程释放对象锁,所以join方法同样会让线程释放对一个对象持有的锁。
参考资料:
http://www.cnblogs.com/dolphin0520/p/3920357.html
相关文章推荐
- C#线程间不能调用剪切板的解决方法
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- C++使用CriticalSection实现线程同步实例
- 基于C++实现的线程休眠代码
- VB读取线程、句柄及写入内存的API代码实例
- C#网络编程基础之进程和线程详解
- C#通过Semaphore类控制线程队列的方法
- C#多线程处理多个队列数据的方法
- C#实现线程安全的简易日志记录方法
- C#中线程同步对象的方法分析
- ASP.NET线程相关配置
- 浅析linux环境下一个进程最多能有多少个线程
- 再谈JavaScript线程
- C#实现终止正在执行的线程
- Java线程编程中的主线程讲解
- 解析Java线程同步锁的选择方法