实现线程同步的方式
方式一:使用Thread里面的join方法
public static void main(String[] args) throws Exception { Thread t1 = Thread1(); Thread t2 = Thread2(); Thread t3 = Thread3(); t1.start(); t1.join(); //主线程让出来等待,直到子线程执行结束,主线程继续执行下去 t2.start(); t2.join(); t3.start(); } static Thread Thread1(){ return new Thread(new Runnable() { public void run() { System.out.println("t1"); } }); } static Thread Thread2(){ return new Thread(new Runnable() { public void run() { System.out.println("t2"); } }); } static Thread Thread3(){ return new Thread(new Runnable() { public void run() { System.out.println("t3"); } }); }
方式二:jdk1.5引入的Executor执行器,使用newSingleThreadExecutor,创建只有一个线程的线程池,所有任务放在一个没有上限的LinkedBlockingQueue队列里(FIFO(先进先出)),等待唯一的单线程来执行任务,保证任务有序执行
public static void main(String[] args) throws Exception { Thread t1 = Thread1(); Thread t2 = Thread2(); Thread t3 = Thread3(); ExecutorService executorService = Executors.newSingleThreadExecutor(); executorService.submit(t1); executorService.submit(t2); executorService.submit(t3); executorService.shutdown(); } static Thread Thread1(){ return new Thread(new Runnable() { public void run() { System.out.println("t1"); } }); } static Thread Thread2(){ return new Thread(new Runnable() { public void run() { System.out.println("t2"); } }); } static Thread Thread3(){ return new Thread(new Runnable() { public void run() { System.out.println("t3"); } }); }
方式三:类似方式二,创建newFixedThreadPool只有一个线程的线程池,同样也是没有上限的LinkedBlockingQueue队列,代码略
方法四:使用juc包下的countDownLatch
public class ThreadTest { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch1 = new CountDownLatch(1); Thread thread1 = thread1(countDownLatch1); thread1.start(); countDownLatch1.await(); CountDownLatch countDownLatch2 = new CountDownLatch(1); Thread thread2 = thread2(countDownLatch2); thread2.start(); countDownLatch2.await(); CountDownLatch countDownLatch3 = new CountDownLatch(1); Thread thread3 = thread3(countDownLatch3); thread3.start(); countDownLatch3.await(); } static Thread thread1(final CountDownLatch countDownLatch) { return new Thread(new Runnable() { @Override public void run() { System.out.println("this is Thread1!"); countDownLatch.countDown(); } }); } static Thread thread2(final CountDownLatch countDownLatch) { return new Thread(new Runnable() { @Override public void run() { System.out.println("this is Thread2!"); countDownLatch.countDown(); } }); } static Thread thread3(final CountDownLatch countDownLatch) { return new Thread(new Runnable() { @Override public void run() { System.out.println("this is Thread3!"); countDownLatch.countDown(); } }); } }
方法五:使用Lock里的condition
package com.ares.thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class PrintABC { int count = 0; //打印次数 Lock lock = new ReentrantLock(); //可重写锁 Condition conditionA = this.lock.newCondition(); Condition conditionB = this.lock.newCondition(); Condition conditionC = this.lock.newCondition(); public class PrintA implements Runnable { @Override public void run() { //while (true) // if (count < 15) { lock.lock(); System.out.print("A"); try { conditionB.signal(); //线程b唤醒,因为a打印完应该打印b conditionA.await(); //线程a进入等待队列 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } // } } } public class PrintB implements Runnable { @Override public void run() { // while (true) // if (count < 15) { lock.lock(); System.out.print("B"); try { conditionC.signal(); conditionB.await(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } //} } } public class PrintC implements Runnable { @Override public void run() { // while (true) // if (count < 15) { lock.lock(); System.out.println("C" + count); //count++;//打印完c后,count++ try { conditionA.signal(); conditionC.await(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } // } } } public static void main(String[] args) { PrintABC printABCD = new PrintABC(); new Thread(printABCD.new PrintA()).start(); new Thread(printABCD.new PrintB()).start(); new Thread(printABCD.new PrintC()).start(); } }
方法六:使用synchronized(object)wait/notifyall
public class MyThread extends Thread { private Object lock; private String showChar; private int showNum; private int printCount = 0; private volatile static int addNumber = 1; public MyThread(Object lock, String showChar, int showNum) { this.lock = lock; this.showChar = showChar; this.showNum = showNum; } @Override public void run() { try { synchronized (lock) { while(true){ if(addNumber % 4 == showNum) { System.out.println(showChar); lock.notifyAll(); addNumber++; printCount++; if(printCount == 3) { break; } }else { lock.wait(); } } } } catch (Exception e) { e.printStackTrace(); } } }
public class Run { public static void main(String[] args) { Object lock = new Object(); MyThread a = new MyThread(lock, "A", 1); MyThread b = new MyThread(lock, "B", 2); MyThread c = new MyThread(lock, "C", 3); a.start(); b.start(); c.start(); } }