Lock只有代码块锁,synchronized有代码块锁和方法锁使用Lock锁,JVM将花费较少的时间来调度线程,性能更好。并且具有更好的扩展性(提供更多的子类)
优先使用顺序:
Lock > 同步代码块(已经进入了方法体,分配了相应资源)> 同步方法(在方
法体之外)
线程通信的目标是使线程间能够互相发送信号。另一方面,线程通信使线程能够等待其他线程的信号。
线程的通信方式
volatile
Wait/Notify机制
join方式
threadLocal
CountDownLatch 并发工具
CyclicBarrier 并发工具
volatile
public class Volatile implements Runnable { private static volatile Boolean flag = true; @Override public void run() { while (flag) { System.out.println(Thread.currentThread().getName() + " - 执行"); } System.out.println("线程结束"); } public static void main(String[] args) { Thread t = new Thread(new Volatile()); t.start(); try { Thread.sleep(5); flag = false; } catch (InterruptedException e) { e.printStackTrace(); } } } Thread-0 - 执行 Thread-0 - 执行 Thread-0 - 执行 Thread-0 - 执行 Thread-0 - 执行 线程结束**WaitNotify **
public class WaitNotify { // 状态锁 private static Object lock = new Object(); private static Integer i = 0; public void odd() { while (i < 10) { synchronized (lock) { if (i % 2 == 1) { System.out.println(Thread.currentThread().getName() + " - " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } i++; lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public void even() { while (i < 10) { synchronized (lock) { if (i % 2 == 0) { System.out.println(Thread.currentThread().getName() + " - " + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } i++; lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public static void main(String[] args) { WaitNotify waitNotify = new WaitNotify(); Thread t1 = new Thread(() -> waitNotify.odd(), "线程1"); Thread t2 = new Thread(() -> waitNotify.even(), "线程2"); t1.start(); t2.start(); } }join
package threadCommunication; public class JoinTest extends Thread { @Override public void run() { try { int sleepTime = (int) (Math.random() * 1000); System.out.println(sleepTime); Thread.sleep(sleepTime); System.out.println("JoinTest end"); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) throws InterruptedException { JoinTest j = new JoinTest(); j.start(); j.join();//当前线程main等待线程对象(j)销毁 System.out.println("main end"); }threadLocal
package sync; public class SequenceNumber { // 定义匿名子类创建ThreadLocal的变量 private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() { // 覆盖初始化方法 public Integer initialValue() { return 0; } }; // 下一个序列号 public int getNextNum() { seqNum.set(seqNum.get() + 1); return seqNum.get(); } private static class TestClient extends Thread { private SequenceNumber sn; public TestClient(SequenceNumber sn) { this.sn = sn; } // 线程产生序列号 public void run() { for (int i = 0; i < 3; i++) { System.out.println("thread[" + Thread.currentThread().getName() + "] sn[" + sn.getNextNum() + "]"); } } } /** * @param args */ public static void main(String[] args) { SequenceNumber sn = new SequenceNumber(); // 三个线程产生各自的序列号 TestClient t1 = new TestClient(sn); TestClient t2 = new TestClient(sn); TestClient t3 = new TestClient(sn); t1.start(); t2.start(); t3.start(); } } thread[Thread-1] sn[1] thread[Thread-1] sn[2] thread[Thread-1] sn[3] thread[Thread-2] sn[1] thread[Thread-2] sn[2] thread[Thread-2] sn[3] thread[Thread-0] sn[1] thread[Thread-0] sn[2] thread[Thread-0] sn[3]