1、wait
public final void wait(long timeout) throws InterruptedException
此方法为Object类的方法,在其他线程调用此对象的 notify()
方法或 notifyAll()
方法,或者超过指定的时间量前,导致当前线程等待。当前线程必须拥有此对象监视器,也就是当前线程必须要有此对象的锁,该方法必须写在synchronized修饰的方法里或synchronized同步代码块里, 否则将抛出运行时异常IllegalMonitorStateException,wait()方法相当于wait(0)方法。
2、notify
public final void notify()
此方法为Object类中的方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait
方法,在对象的监视器上等待。 该方法必须写在synchronized修饰的方法里或synchronized同步代码块里, 否则将抛出运行时异常IllegalMonitorStateException。
public final void notifyAll()
唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait
方法,在对象的监视器上等待。
如http://chenzehe.iteye.com/admin/blogs/1550701中的代码:
public class Info { private String country; private String city; private boolean flag = true; // true表示可以生产,但不能消费,false表示可以消费,但不能生产 public synchronized void set(String country, String city) { if (!flag) { try { super.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.country = country; try { Thread.sleep(300); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.city = city; this.flag = false; super.notify(); } public synchronized void get() { if (flag) { try { super.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("country:" + this.country + "->city:" + this.city); this.flag=true; super.notify(); } public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
3、join
public final void join(long millis) throws InterruptedException
是Thrad类中的方法,等待该线程终止的时间最长为millis
毫秒。超时为 0
意味着要一直等下去。public final void join()相当于join(0)。也就是使异步执行的线程变成同步,即等到该线程执行完成返回才往下执行下面代码。
如http://chenzehe.iteye.com/admin/blogs/1741137中代码:
public class MyRunnable implements Runnable { public static volatile int n = 0; public void run() { for (int i = 0; i < 10; i++) { try { n = n + 1; Thread.sleep(10); } catch (Exception e) { // TODO: handle exception } } } } public class MainTest { public static void main(String[] args) throws Exception { Thread[] threads = new Thread[100]; // 创建100个线程 for (int i = 0; i < threads.length; i++) { threads[i] = new Thread(new MyRunnable()); } // 启动100个线程 for (int i = 0; i < threads.length; i++) { threads[i].start(); } // 让100个线程都执行完 for (int i = 0; i < threads.length; i++) { threads[i].join(); } System.out.println(MyRunnable.n); } }
下面代码为join()的实现代码,发现join()也为synchronized方法,并且是调用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; } } }
4、sleep
public static void sleep(long millis) throws InterruptedException
Thread类中的方法,在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。使当前线程暂停执行一段时间,让其它线程有机会执行,但它并不释放当前锁,其它线程仍不能访问共享数据。
5、yield
Thread类中的方法,与sleep类似,只是不能由用户定义多长时间,并且yield()只能让具有同优先级的程序有执行的机会。