赞
踩
join主要是让父线程等待子线程结束之后父线程才能继续运行
public static void main(String[] args) throws InterruptedException { System.out.println("---开启线程1---"); MyThread t1 = new MyThread("线程1"); t1.start(); t1.join(); System.out.println("---开启线程2---"); MyThread t2 = new MyThread("线程2"); t2.start(); t2.join(); System.out.println("---开启线程3---"); MyThread t3 = new MyThread("线程3"); t3.start(); t3.join(); } static class MyThread extends Thread { public MyThread(String name){ super(name); } @Override public void run() { super.run(); System.out.println(Thread.currentThread().getName()+"执行了"); } }
打印结果
---开启线程1---
线程1执行了
---开启线程2---
线程2执行了
---开启线程3---
线程3执行了
public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println("---开启线程1---"); FutureTask<String> f1 = new FutureTask<>(new MyCall()); Thread t1 = new Thread(f1,"线程1"); t1.start(); System.out.println("线程1返回结果: " + f1.get()); System.out.println("---开启线程2---"); FutureTask<String> f2 = new FutureTask<>(new MyCall()); Thread t2 = new Thread(f2,"线程2"); t2.start(); System.out.println("线程2返回结果: " + f2.get()); System.out.println("---开启线程3---"); FutureTask<String> f3 = new FutureTask<>(new MyCall()); Thread t3 = new Thread(f3,"线程3"); t3.start(); System.out.println("线程3返回结果: " + f3.get()); } static class MyCall implements Callable<String> { @Override public String call() throws Exception { return Thread.currentThread().getName(); } }
打印结果
---开启线程1---
线程1返回结果: 线程1
---开启线程2---
线程2返回结果: 线程2
---开启线程3---
线程3返回结果: 线程3
现在有如下3个线程
public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println("---开启线程1---"); Thread t1 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(500); System.out.println("线程1执行了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程1"); t1.start(); System.out.println("---开启线程2---"); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(200); System.out.println("线程2执行了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程2"); t2.start(); System.out.println("---开启线程3---"); Thread t3 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(100); System.out.println("线程3执行了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程3"); t3.start(); }
它们的执行结果是
---开启线程1---
---开启线程2---
---开启线程3---
线程3执行了。。。
线程2执行了。。。
线程1执行了。。。
上面的输出是按照3、2、1输出的。如果现在要按照1、2、3的顺序进行输出,每个线程的sleep时间不能修改,该如何去处理?可以借助CountDownLatch
private static CountDownLatch c1 = new CountDownLatch(1); private static CountDownLatch c2 = new CountDownLatch(1); public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println("---开启线程1---"); Thread t1 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(500); System.out.println("线程1执行了。。。"); c1.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程1"); t1.start(); System.out.println("---开启线程2---"); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { c1.await(); Thread.sleep(200); System.out.println("线程2执行了。。。"); c2.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程2"); t2.start(); System.out.println("---开启线程3---"); Thread t3 = new Thread(new Runnable() { @Override public void run() { try { c2.await(); Thread.sleep(100); System.out.println("线程3执行了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程3"); t3.start(); }
它们的执行结果是
---开启线程1---
---开启线程2---
---开启线程3---
线程1执行了。。。
线程2执行了。。。
线程3执行了。。。
private final static Object lock1 = new Object(); private final static Object lock2 = new Object(); public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println("---开启线程1---"); Thread t1 = new Thread(new Runnable() { @Override public void run() { synchronized (lock1) { try { lock1.wait(); Thread.sleep(500); System.out.println("线程1执行了。。。"); lock1.notify(); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "线程1"); t1.start(); Thread.sleep(10);//这个主要保证线程开启的顺序 System.out.println("---开启线程2---"); Thread t2 = new Thread(new Runnable() { @Override public void run() { synchronized (lock1) { try { lock1.notify(); lock1.wait(); Thread.sleep(200); System.out.println("线程2执行了。。。"); synchronized (lock2) { lock2.notify(); } } catch (InterruptedException e) { e.printStackTrace(); } } } }, "线程2"); t2.start(); Thread.sleep(10); System.out.println("---开启线程3---"); Thread t3 = new Thread(new Runnable() { @Override public void run() { synchronized (lock2) { try { lock2.wait(); Thread.sleep(100); System.out.println("线程3执行了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } } }, "线程3"); t3.start(); }
打印结果
---开启线程1---
---开启线程2---
---开启线程3---
线程1执行了。。。
线程2执行了。。。
线程3执行了。。。
private static Lock lock = new ReentrantLock(); private static Condition condition1 = lock.newCondition(); private static Condition condition2 = lock.newCondition(); public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println("---开启线程1---"); Thread t1 = new Thread(new Runnable() { @Override public void run() { try { lock.lock(); condition1.await(); Thread.sleep(500); System.out.println("线程1执行了。。。"); condition1.signal(); lock.unlock(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程1"); t1.start(); System.out.println("---开启线程2---"); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { lock.lock(); condition1.signal(); condition1.await(); Thread.sleep(200); System.out.println("线程2执行了。。。"); condition2.signal(); lock.unlock(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程2"); t2.start(); System.out.println("---开启线程3---"); Thread t3 = new Thread(new Runnable() { @Override public void run() { try { lock.lock(); condition2.await(); Thread.sleep(100); System.out.println("线程3执行了。。。"); lock.unlock(); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程3"); t3.start(); }
打印结果
---开启线程1---
---开启线程2---
---开启线程3---
线程1执行了。。。
线程2执行了。。。
线程3执行了。。。
private static CyclicBarrier barrier1 = new CyclicBarrier(2); private static CyclicBarrier barrier2 = new CyclicBarrier(2); public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println("---开启线程1---"); Thread t1 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(500); System.out.println("线程1执行了。。。"); barrier1.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }, "线程1"); t1.start(); System.out.println("---开启线程2---"); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { barrier1.await(); Thread.sleep(200); System.out.println("线程2执行了。。。"); barrier2.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }, "线程2"); t2.start(); System.out.println("---开启线程3---"); Thread t3 = new Thread(new Runnable() { @Override public void run() { try { barrier2.await(); Thread.sleep(100); System.out.println("线程3执行了。。。"); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } } }, "线程3"); t3.start(); }
打印结果
---开启线程1---
---开启线程2---
---开启线程3---
线程1执行了。。。
线程2执行了。。。
线程3执行了。。。
private static ExecutorService executorService = Executors.newSingleThreadExecutor(); public static void main(String[] args) throws InterruptedException, ExecutionException { System.out.println("---开启线程1---"); Thread t1 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(500); System.out.println("线程1执行了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程1"); System.out.println("---开启线程2---"); Thread t2 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(200); System.out.println("线程2执行了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程2"); System.out.println("---开启线程3---"); Thread t3 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(100); System.out.println("线程3执行了。。。"); } catch (InterruptedException e) { e.printStackTrace(); } } }, "线程3"); executorService.submit(t1); executorService.submit(t2); executorService.submit(t3); }
打印结果
---开启线程1---
---开启线程2---
---开启线程3---
线程1执行了。。。
线程2执行了。。。
线程3执行了。。。
其实最常见的还是使用多线程化的线程池去实现。
private static ExecutorService executorService = Executors.newFixedThreadPool(3); public static void main(String[] args) throws InterruptedException, ExecutionException { long start = System.currentTimeMillis(); ArrayList<Future<String>> futureList = new ArrayList<Future<String>>(); ArrayList<String> names = new ArrayList<String>(); for (int i = 0; i < 3; i++) { futureList.add(executorService.submit(new MyCall(i + ""))); } for (int i = 0; i < 3; i++) { Future<String> future = futureList.get(i); String value = future.get(); System.out.println("线程"+value+"执行了"); } long spendTime = System.currentTimeMillis() - start; System.out.println("花费时间---"+spendTime); } static class MyCall implements Callable<String> { private String name; public MyCall(String name) { this.name = name; } @Override public String call() throws Exception { switch (name){ case "0": Thread.sleep(3000); break; case "1": Thread.sleep(2000); break; case "2": Thread.sleep(1000); break; } return name; } }
打印结果
线程0执行了
线程1执行了
线程2执行了
花费时间---3006
常见的问题:
相信上面的问题应该不难了。。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。