超时等待(time waiting)状态,超过限制时间后,该线程将返回到就绪(runnable)状态。
Thread类中常用的方法:
1 2 sleep(long millis); sleep(long millis, int nanoseconds);
sleep让线程睡眠,交出CPU,让CPU去执行其他任务。此时该线程将处于阻塞的状态,并且在其睡眠时间内,该线程不会获得执行的机会,即使系统中已没有其他可执行线程,处于sleep中的线程也不会执行。需要注意的是,sleep方法不会释放锁,也就是说如果当前线程持有对某个对象的锁,则调用sleep方法后,其他线程将无法访问这个对象 。
1 2 3 join(); join(long millis); join(long millis, int nanoseconds);
主线程将等待当前线程执行完毕,或者主线程等待一端时间。
suspend(),resume(),stop(),即暂停,恢复,停止方法已废弃,原因是调用后线程不会释放已占用的资源(比如锁),容易引起死锁问题。
线程获取synchronized锁失败,将进入同步队列,状态变为Blocked阻塞态。当其他线程释放该锁,该释放行为将唤醒阻塞在同步队列中的线程,使其重新尝试获取锁。
等待/通知机制
每个锁对象存在两种队列:等待队列,同步队列。参考“Java并发编程的艺术”图4-3.
等待/通知方法是任意Java对象都具备的,因为这些方法被定义在所有对象的超类java.lang.Object上。
使用wait()方法,notify()方法,notifyAll()方法时,需要先对调用对象加锁。
notify():任意通知在同一个对象锁上等待的一个线程,使其从wait()方法返回(返回到就绪态runnable)。返回的前提有两个,一是等待线程已接收到了(或刚刚接收过了)notify()或notifyAll()信号(从等待队列转至同步队列,从wait状态转至blocked状态);二是该等待线程成功获取到了该同一对象锁(从同步队列转出,从blocked状态转至runnable状态)。
notifyAll():通知在同一个对象锁上等待的所有线程,使某一线程从wait()方法返回(返回到就绪态runnable)。返回的前提有两个,一是等待线程已接收到了(或刚刚接收过了)notify()或notifyAll()信号(从等待队列转至同步队列,从wait状态转至blocked状态);二是该等待线程成功获取到了该同一对象锁(从同步队列转出,从blocked状态转至runnable状态)。
注意:线程调用notify()或notifyAll()方法不会立即释放锁!该方法只是进行发送通知的行为!释放锁还是要等到synchronized代码块或synchronized方法执行完,才去释放锁。
wait()方法:调用该方法的线程进入到锁对象的等待队列,从running状态进入到wait状态,只有等待其他线程的通知或中断才会返回(返回到就绪态runnable)。注意,调用wait()方法后,会立即释放锁。
wait(long)/wait(long , int):同wait()方法,但超过规定时间后,自动从等待队列转至同步队列,从wait状态转至blocked状态。
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 import java.util.concurrent.TimeUnit;public class ApplicationDemo { static boolean flag = true ; static final Object lock = new Object(); static class Wait implements Runnable { public void run () { synchronized (lock) { while (flag) { try { System.out.println(Thread.currentThread() + " flag is true. wait..." ); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.ptintln(Thread.currentThread() + " flag is false. running..." ); } } } static class Notify implements Runnable { public void run () { synchronized (lock) { System.out.println(Thread.currentThread() + " hold lock. notify now" ); lock.notifyAll(); flag = false ; try { TimeUnit.SECONDS.sleep(5 ); } catch (InterruptedException e) { e.printStackTrace(); } } synchronized (lock) { System.out.println(Thread.currentThread() + " hold lock again." ); try { TimeUnit.SECONDS.sleep(5 ); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main (String[] args) throw Exception { Thread waitThread = new Thread(new Wait(), "WaitThread" ); waitThread.start(); TimeUnit.SECONDS.sleep(1 ); Thread notifyThread = new Thread(new Notify(), "NotifyThread" ); notifyThread.start(); try { waitThread.join(); notifyThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }
摘自/参考链接
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class ApplicationDemo { private AtomicInteger atomicI = new AtomicInteger(0 ); private void safeCount () { for (;;) { int i = atomicI.get(); boolean suc = atomicI.compareAndSet(i, i++); if (suc) { break ; } } } public static void main (String[] args) { final ApplicationDemo applicationDemo = new ApplicationDemo(); List<Thread> ts = new ArrayList<>(600 ); for (int i = 0 ; i < 100 ; ++i) { Thread t = new Thread(() -> { for ( int j = 0 ; j < 1000 ; ++j) { applicationDemo.safeCount(); } }); ts.add(t); } for ( Thread t : ts) { t.start(); } for (Thread t : ts) { try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class ApplicationDemo { public static void main (String[] args) { new Thread(new Blocked(), "BlockedThread - 1" ).start(); } static class Blocked implements Runnable { @Override public void run () { synchronized (Blocked.class) { while (true ) { System.out.println("..." ); } } } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class ApplicationDemo { private int i = 10 ; private final Object object = new Object(); class MyThread extends Thread { @Override public void run () { synchronized (object) { ++i; } } } public static void main (String[] args) { ApplicationDemo applicationDemo = new ApplicationDemo(); MyThread td_1 = application.new MyThread () ; MyThread td_2 = application.new MyThread () ; td_1.start(); td_2.start(); try { td_1.join(); td_2.join(); } catch (InterruptedException e) { e.printStackTrace(); } } }