1、线程安全
并发、并行概念
并行:指两个或者多个事件在同一时刻发生 (边吃饭边打电话同一时间发生)
并发:指两个或多个事件在同一时间间隔发生(吃饭电话吃饭交替执行)
线程状态:
NEW: 新建状态,线程被创建且未启动的状态
RUNNABLE: 就绪状态,调用start()之后,运行之前的状态
RUNNING: 运行状态,run()正在执行时线程的状态
BLOCKED: 阻塞状态
DEAD: 终止状态,run()结束后的状态,此状态不可逆转
线程安全核心理念就是“要么只读,要么加锁”
java中并发包
- 线程同步类:CountDownLatch、 Semaphore、 CyclicBarrier 等
- 并发集合类:ConcurrentHashMap、ConcurrentSkipListMap、 CopyOnWriteArrayList、 BlockingQueue 等
- 线程管理类:ThreadLocal
- 锁相关类:Lock、ReentrantLock
2、java中实现锁
3、线程同步
volatile
多线程共享变量的可见性,类似synchronized, 但不具备synchronized的互斥性
信号量同步
1、CountDownLatch: 比如有一个主线程main,它要等待其他3个任务执行完毕之后才能执行;如果其中一个线程出现异常,主线程main一直阻塞
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class CountDownLatchTest { public static void main(String[] args) throws InterruptedException { CountDownLatch count = new CountDownLatch(3);
new TranslateThread("1st", count).start(); new TranslateThread("2nd", count).start(); new TranslateThread("3rd", count).start();
count.await(); System.out.println("所有线程执行完毕"); } }
class TranslateThread extends Thread { private String content; private CountDownLatch count; public TranslateThread(String content, CountDownLatch count) { this.content = content; this.count = count; }
@Override public void run() {
if (Math.random() > 0.5) { throw new RuntimeException("出现异常"); } System.out.println(content + " 已完成"); count.countDown(); } }
|
运行结果
1 2 3 4
| Exception in thread "Thread-0" java.lang.RuntimeException: 存在非法字符 at com.concurrency.TranslateThread.run(CountDownLatchTest.java:46) 2nd content的翻译已经完成,译文是... 3rd content的翻译已经完成,译文是...
|
2、Semaphore: 可以控制同时访问的线程个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| public class CustomCheckWindow { public static void main(String[] args) { Semaphore semaphore = new Semaphore(3); for (int i = 1; i <= 5; i++) { new SecurityCheckThread(i, semaphore).start(); } }
private static class SecurityCheckThread extends Thread { private int seq; private Semaphore semaphore;
public SecurityCheckThread(int seq, Semaphore semaphore) { this.seq = seq; this.semaphore = semaphore; }
@Override public void run() { try { semaphore.acquire(); System.out.println("No." + seq + " 乘客,正在检验中"); if (seq % 2 == 0) { Thread.sleep(1000); System.out.println("No." + seq + " 乘客,身份可疑,不能出国!"); }
} catch (InterruptedException e) { e.printStackTrace(); } finally { semaphore.release(); System.out.println("No." + seq + " 乘客已完成服务"); } } } }
|
运行结果
1 2 3 4 5 6 7 8 9 10 11 12
| No.1 乘客,正在检验中 No.3 乘客,正在检验中 No.2 乘客,正在检验中 No.3 乘客已完成服务。 No.1 乘客已完成服务。 No.4 乘客,正在检验中 No.5 乘客,正在检验中 No.5 乘客已完成服务。 No.2乘客, 身份可疑,不能出国! No.2 乘客已完成服务。 No.4乘客, 身份可疑,不能出国! No.4 乘客已完成服务。
|