假设我要让3个线程按照顺序打印ABC,那么可使用Join,若是要求多线程按顺序循环打印,则不能用join了java
join是Thread类的一个方法,启动线程后直接调用。在不少状况下,主线程生成并起动了子线程,若是子线程里要进行大量的耗时的运算,主线程每每将于子线程以前结束,可是若是主线程处理完其余的事务后,须要用到子线程的处理结果,也就是主线程须要等待子线程执行完成以后再结束,这个时候就要用到join()方法了。git
join()的做用是:“等待该线程终止”,这里须要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。github
具体代码:多线程
package googleTest; public class ThreadTest { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new Runner("A")); Thread t2 = new Thread(new Runner("B")); Thread t3 = new Thread(new Runner("C")); t1.start(); t1.join(); t2.start(); t2.join(); t3.start(); t3.join(); } } class Runner implements Runnable{ public String name; Runner(String name) { this.name=name; } @Override public void run() { System.out.println(name+""); } }
</pre>lock时注意unlock就能够啦</p><p class="p1"><pre name="code" class="java">import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ThreadTest3 { private static Lock lock=new ReentrantLock(); private static int state = 0; static class ThreadA extends Thread { @Override public void run() { lock.lock(); if (state % 3 == 0) { System.out.println("A"); state++; } lock.unlock(); } } static class ThreadB extends Thread { @Override public void run() { lock.lock(); if (state % 3 == 1) { System.out.println("B"); state++; } lock.unlock(); } } static class ThreadC extends Thread { @Override public void run() { lock.lock(); if (state % 3 == 2) { System.out.println("C"); state++; } lock.unlock(); } } public static void main(String[] args) { new ThreadA().start(); new ThreadB().start(); new ThreadC().start(); } }
就拿生产者消费者模式来讲,当仓库满了的时候,又再执行到 生产者 线程的时候,会把 该 生产者 线程进行阻塞,再唤起一个线程.并发
可是此时唤醒的是消费者线程仍是生产者线程,是未知的。若是再次唤醒的仍是生产者线程,那么还须要把它进行阻塞,再唤起一个线程,再此循环,直到唤起的是消费者线程。这样就可能存在 时间或者资源上的浪费,ide
因此说 有了Condition 这个东西。Condition 用 await() 代替了 Object 的 wait() 方法,用 signal() 方法代替 notify() 方法。注意:Condition 是被绑定到 Lock 中,要建立一个 Lock 的 Condition 必须用 newCondition() 方法。ui
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ThreadTest2 { private static Lock lock = new ReentrantLock(); private static int count = 0; private static Condition A = lock.newCondition(); private static Condition B = lock.newCondition(); private static Condition C = lock.newCondition(); static class ThreadA extends Thread { @Override public void run() { lock.lock(); try { for (int i = 0; i < 10; i++) { while (count % 3 != 0) A.await(); // 会释放lock锁 System.out.print("A"); count++; B.signal(); // 唤醒相应线程 } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } static class ThreadB extends Thread { @Override public void run() { lock.lock(); try { for (int i = 0; i < 10; i++) { while (count % 3 != 1) B.await(); System.out.print("B"); count++; C.signal(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } static class ThreadC extends Thread { @Override public void run() { lock.lock(); try { for (int i = 0; i < 10; i++) { while (count % 3 != 2) C.await(); System.out.println("C"); count++; A.signal(); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException { new ThreadA().start(); new ThreadB().start(); ThreadC threadC = new ThreadC(); threadC.start(); threadC.join(); System.out.println(count); } }
Semaphore为并发包中提供用于控制某资源同时能够被几个线程访问的类。通常用于限制线程访问的资源个数。也可用于线程间的信号传递。this
import java.util.concurrent.Semaphore; public class ThreadTest4 { private static Semaphore A = new Semaphore(1); private static Semaphore B = new Semaphore(1); private static Semaphore C = new Semaphore(1); static class ThreadA extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { A.acquire(); System.out.print("A"); B.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } static class ThreadB extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { B.acquire(); System.out.print("B"); C.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } static class ThreadC extends Thread { @Override public void run() { try { for (int i = 0; i < 10; i++) { C.acquire(); System.out.println("C"); A.release(); } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { B.acquire(); C.acquire(); // 开始只有A能够获取, BC都不能够获取, 保证了A最早执行 new ThreadA().start(); new ThreadB().start(); new ThreadC().start(); } }