等待(wait) 和通知(notify)
这两个方法来自Object类, 使用前必须先获得目标的锁.
wait()使用场景必须包含在synchronzied语句中., 当调用后,线程释放锁, 进入object对象的等待队列, 等待notify() .notifyAll()去唤醒.
package threads; public class WaitAndNotify { final static Object ob = new Object(); public static class T1 extends Thread { @Override public void run() { synchronized (ob) { System.out.println(System.currentTimeMillis() + " : " + "T1.start"); try { System.out.println(System.currentTimeMillis() + " : " + "T1.wait"); ob.wait();//放开锁,停止继续执行下一步 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() + " : " + "T1.end"); } } } public static class T2 extends Thread { @Override public void run() { synchronized (ob) { System.out.println(System.currentTimeMillis() + " : " + "T2.start"); ob.notify();// 提示其他进程去获取锁 System.out.println(System.currentTimeMillis() + " : " + "T2.end"); try { Thread.sleep(2000);//占用锁没有放开.导致t2end比t1end早两秒 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public static void main(String[] args) { Thread t1 = new T1(); Thread t2 = new T2(); t1.start(); t2.start(); } } 1568212250034 : T1.start 1568212250034 : T1.wait 1568212250034 : T2.start 1568212250034 : T2.end 两秒 1568212252034 : T1.end
等待线程结束join() 和 谦让yield()
有些时候我们需要一个线程依赖其他线程执行完毕才能,才能操作这是使用join()
join 分为2种 , 第一种是无限等待阻塞进程,直到目标线程执行完毕,
第二种是有时间限制, 过了时间就不等了,继续执行下一步.
private volatile static int i = 0; public static class Nums extends Thread{ @Override public void run() { for ( i = 0; i < 10000999; i++); } } public static void main(String[] args) throws InterruptedException { Nums nums = new Nums(); // 选择目标线程对象, 而不是Thread nums.start(); //0 nums.join(); //10000999 System.out.println(i); }
yiled()是静态方法,使用后 当前线程让出CPU,继续参与CPU的争夺适用于优先级低,害怕占用太多资源的线程.
public class YieldA { public static class RunCPU extends Thread{ public RunCPU(String name) { super.setName(name); } @Override public void run() { for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName() + ": " + i); if(i == 30) { Thread.yield(); try { Thread.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } public static void main(String[] args) { RunCPU runCPU = new RunCPU("run111111"); RunCPU runCPU2 = new RunCPU("run222222"); runCPU.start(); // 到30让出cpu给runCPU2 runCPU2.start();// 到30让出cpu给runCPU } }