1. 线程基础知识

1.1 Java 线程状态

1.1.1 线程生命周期
线程状态转换图:

    NEW
     │
     │ start()
     ▼
  RUNNABLE ◄──────────────────────────────────────┐
     │                                            │
     │ 等待锁/IO/sleep()                           │ notify()/
     ▼                                            │ notifyAll()
  BLOCKED ──────► WAITING ──────► TIMED_WAITING ───┤
     │              │                │            │
     │              │ wait()         │ sleep()    │
     │              │ join()         │ wait(time) │
     │              │ park()         │ join(time) │
     │              │                │ parkUntil()│
     │              │                │            │
     │              ▼                ▼            │
     └──────────► TERMINATED ◄──────────────────────┘
                    │
                    │ 线程结束
                    ▼
                  [END]
1.1.2 线程状态详解

NEW(新建)

// 线程已创建但尚未启动
Thread thread = new Thread(() -> {
    System.out.println("Hello World");
});
// 此时线程状态为 NEW
System.out.println(thread.getState()); // NEW

RUNNABLE(可运行)

// 线程正在运行或准备运行
thread.start();
// 此时线程状态为 RUNNABLE
System.out.println(thread.getState()); // RUNNABLE

BLOCKED(阻塞)

// 线程等待获取同步锁
public class BlockedExample {
    private static final Object lock = new Object();
    
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(10000); // 持有锁10秒
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        Thread t2 = new Thread(() -> {
            synchronized (lock) { // 等待获取锁,状态为 BLOCKED
                System.out.println("Got the lock");
            }
        });
        
        t1.start();
        Thread.sleep(100); // 确保 t1 先获取锁
        t2.start();
        Thread.sleep(100);
        
        System.out.println("t2 state: " + t2.getState()); // BLOCKED
    }
}

WAITING(等待)

// 线程无限期等待另一个线程的特定操作
public class WaitingExample {
    private static final Object lock = new Object();
    
    public static void main(String[] args) throws InterruptedException {
        Thread waiter = new Thread(() -> {
            synchronized (lock) {
                try {
                    lock.wait(); // 状态变为 WAITING
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        
        waiter.start();
        Thread.sleep(100);
        
        System.out.println("waiter state: " + waiter.getState()); // WAITING
        
        // 唤醒等待的线程
        synchronized (lock) {
            lock.notify();
        }
    }
}

TIMED_WAITING(定时等待)

// 线程等待指定的时间
public class TimedWaitingExample {
    public static void main(String[] args) throws InterruptedException {
        Thread sleeper = new Thread(() -> {
            try {
                Thread.sleep(5000); // 状态为 TIMED_WAITING
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });
        
        sleeper.start();
        Thread.sleep(100);
        
        System.out.println("sleeper state: " + sleeper.getState()); // TIMED_WAITING
    }
}

TERMINATED(终止)

// 线程已完成执行
Thread finishedThread = new Thread(() -> {
    System.out.println("Task completed");
});

finishedThread.start();
finishedThread.join(); // 等待线程完成

System.out.println("finished state: " + finishedThread.getState()); // TERMINATED

1.2 线程监控指标

1.2.1 关键指标
// 线程监控指标收集器
import java.lang.management.*;
import java.util.*;

public class ThreadMetricsCollector {
    private static final ThreadMXBean threadBean = 
        ManagementFactory.getThreadMXBean();
    
    public static class ThreadMetrics {
        public final int liveThreads;
        public final int peakThreads;
        public final int daemonThreads;
        public final long totalStartedThreads;
        public final Map<Thread.State, Integer> threadsByState;
        public final List<ThreadInfo> deadlockedThreads;
        
        public ThreadMetrics() {
            this.liveThreads = threadBean.getThreadCount();
            this.peakThreads = threadBean.getPeakThreadCount();
            this.daemonThreads = threadBean.getDaemonThreadCount();
            this.totalStartedThreads = threadBean.getTotalStartedThreadCount();
            this.threadsByState = getThreadsByState();
            this.deadlockedThreads = getDeadlockedThreads();
        }
        
        private Map<Thread.State, Integer> getThreadsByState() {
            Map<Thread.State, Integer> stateCount = new EnumMap<>(Thread.State.class);
            
            // 初始化所有状态计数为0
            for (Thread.State state : Thread.State.values()) {
                stateCount.put(state, 0);
            }
            
            // 统计各状态线程数量
            long[] threadIds = threadBean.getAllThreadIds();
            ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadIds);
            
            for (ThreadInfo info : threadInfos) {
                if (info != null) {
                    Thread.State state = info.getThreadState();
                    stateCount.put(state, stateCount.get(state) + 1);
                }
            }
            
            return stateCount;
        }
        
        private List<ThreadInfo> getDeadlockedThreads() {
            List<ThreadInfo> deadlocked = new ArrayList<>();
            
            // 检查死锁
            long[] deadlockedThreadIds = threadBean.findDeadlockedThreads();
            if (deadlockedThreadIds != null) {
                ThreadInfo[] threadInfos = threadBean.getThreadInfo(deadlockedThreadIds);
                deadlocked.addAll(Arrays.asList(threadInfos));
            }
            
            return deadlocked;
        }
        
        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("=== Thread Metrics ===\n");
            sb.append(String.format("Live Threads: %d\n", liveThreads));
            sb.append(String.format("Peak Threads: %d\n", peakThreads));
            sb.append(String.format("Daemon Threads: %d\n", daemonThreads));
            sb.append(String.format("Total Started: %d\n", totalStartedThreads));
            
            sb.append("\nThreads by State:\n");
            for (Map.Entry<Thread.State, Integer> entry : threadsByState.entrySet()) {
                if (entry.getValue() > 0) {
                    sb.append(String.format("  %s: %d\n", entry.getKey(), entry.getValue()));
                }
            }
            
            if (!deadlockedThreads.isEmpty()) {
                sb.append(String.format("\nDEADLOCK DETECTED! %d threads involved\n", 
                    deadlockedThreads.size()));
            }
            
            return sb.toString();
        }
    }
    
    public static ThreadMetrics collect() {
        return new ThreadMetrics();
    }
    
    public static void main(String[] args) throws InterruptedException {
        // 创建一些测试线程
        createTestThreads();
        
        // 定期收集指标
        for (int i = 0; i < 10; i++) {
            ThreadMetrics metrics = collect();
            System.out.println(metrics);
            System.out.println("=".repeat(50));
            Thread.sleep(5000);
        }
    }
    
    private static void createTestThreads() {
        // 创建一些不同状态的线程用于测试
        
        // RUNNABLE 线程
        new Thread(() -> {
            while (true) {
                // 忙等待
                Math.random();
            }
        }, "BusyThread").start();
        
        // TIMED_WAITING 线程
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "SleepingThread").start();
        
        // WAITING 线程
        Object waitLock = new Object();
        new Thread(() -> {
            synchronized (waitLock) {
                try {
                    waitLock.wait();
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }, "WaitingThread").start();
    }
}

2. VisualVM 线程视图

2.1 Threads 标签页界面

┌─────────────────────────────────────────────────────────────┐
│                        Threads                              │
├─────────────────────────────────────────────────────────────┤
│  线程时间线图表                                              │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ Thread Timeline                                         │ │
│  │                                                         │ │
│  │ main          ████████████████████████████████████████  │ │
│  │ Thread-1      ████████████████████████████████████████  │ │
│  │ Thread-2      ████████████████████████████████████████  │ │
│  │ GC Thread     ████████████████████████████████████████  │ │
│  │ Finalizer     ████████████████████████████████████████  │ │
│  │                                                         │ │
│  │ 绿色: RUNNABLE  黄色: BLOCKED  红色: WAITING             │ │
│  │ 蓝色: TIMED_WAITING  灰色: TERMINATED                   │ │
│  └─────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│  线程详细信息                                                │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ Name: main                    State: RUNNABLE           │ │
│  │ Priority: 5                   Daemon: false             │ │
│  │ Thread ID: 1                  Native ID: 12345          │ │
│  │                                                         │ │
│  │ Stack Trace:                                            │ │
│  │   java.lang.Thread.sleep(Native Method)                │ │
│  │   com.example.Main.main(Main.java:25)                  │ │
│  └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

2.2 线程时间线分析

2.2.1 颜色编码含义

状态颜色映射

  • 绿色 (RUNNABLE):线程正在运行或可以运行
  • 黄色 (BLOCKED):线程被阻塞,等待获取同步锁
  • 红色 (WAITING):线程无限期等待
  • 蓝色 (TIMED_WAITING):线程定时等待
  • 灰色 (TERMINATED):线程已终止
2.2.2 时间线模式分析
// 创建不同模式的线程用于观察
public class ThreadPatternDemo {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();
    
    public static void main(String[] args) {
        // 模式1:CPU密集型线程(持续绿色)
        createCpuIntensiveThread();
        
        // 模式2:IO密集型线程(绿色和蓝色交替)
        createIoIntensiveThread();
        
        // 模式3:锁竞争线程(绿色和黄色交替)
        createLockContentionThreads();
        
        // 模式4:生产者-消费者线程(多种颜色交替)
        createProducerConsumerThreads();
        
        // 保持主线程运行
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    // CPU密集型线程 - 持续RUNNABLE状态
    private static void createCpuIntensiveThread() {
        Thread cpuThread = new Thread(() -> {
            while (true) {
                // 执行计算密集型任务
                double result = 0;
                for (int i = 0; i < 1000000; i++) {
                    result += Math.sqrt(i) * Math.sin(i);
                }
                
                // 偶尔让出CPU
                if (Math.random() < 0.001) {
                    Thread.yield();
                }
            }
        }, "CPU-Intensive-Thread");
        cpuThread.start();
    }
    
    // IO密集型线程 - RUNNABLE和TIMED_WAITING交替
    private static void createIoIntensiveThread() {
        Thread ioThread = new Thread(() -> {
            while (true) {
                try {
                    // 模拟IO操作
                    System.out.println("Performing IO operation...");
                    
                    // 模拟IO等待
                    Thread.sleep(100 + (int)(Math.random() * 200));
                    
                    // 模拟处理数据
                    for (int i = 0; i < 10000; i++) {
                        Math.random();
                    }
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "IO-Intensive-Thread");
        ioThread.start();
    }
    
    // 锁竞争线程 - RUNNABLE和BLOCKED交替
    private static void createLockContentionThreads() {
        for (int i = 0; i < 3; i++) {
            final int threadId = i;
            Thread lockThread = new Thread(() -> {
                while (true) {
                    synchronized (lock1) {
                        try {
                            // 持有锁一段时间
                            Thread.sleep(50 + (int)(Math.random() * 100));
                            
                            // 执行一些工作
                            for (int j = 0; j < 10000; j++) {
                                Math.random();
                            }
                            
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            break;
                        }
                    }
                    
                    // 释放锁后稍作休息
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }, "Lock-Contention-Thread-" + threadId);
            lockThread.start();
        }
    }
    
    // 生产者-消费者线程 - 多种状态交替
    private static void createProducerConsumerThreads() {
        java.util.concurrent.BlockingQueue<String> queue = 
            new java.util.concurrent.ArrayBlockingQueue<>(10);
        
        // 生产者线程
        Thread producer = new Thread(() -> {
            int count = 0;
            while (true) {
                try {
                    String item = "Item-" + (++count);
                    queue.put(item); // 可能会WAITING如果队列满了
                    System.out.println("Produced: " + item);
                    
                    // 生产间隔
                    Thread.sleep(50 + (int)(Math.random() * 100));
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "Producer-Thread");
        
        // 消费者线程
        Thread consumer = new Thread(() -> {
            while (true) {
                try {
                    String item = queue.take(); // 可能会WAITING如果队列空了
                    System.out.println("Consumed: " + item);
                    
                    // 处理时间
                    Thread.sleep(100 + (int)(Math.random() * 200));
                    
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "Consumer-Thread");
        
        producer.start();
        consumer.start();
    }
}

2.3 线程详细信息分析

2.3.1 线程属性解读
// 线程信息分析器
import java.lang.management.*;

public class ThreadInfoAnalyzer {
    private static final ThreadMXBean threadBean = 
        ManagementFactory.getThreadMXBean();
    
    public static void analyzeThread(long threadId) {
        ThreadInfo threadInfo = threadBean.getThreadInfo(threadId, Integer.MAX_VALUE);
        
        if (threadInfo == null) {
            System.out.println("Thread not found: " + threadId);
            return;
        }
        
        System.out.println("=== Thread Analysis ===");
        System.out.println("Thread ID: " + threadInfo.getThreadId());
        System.out.println("Thread Name: " + threadInfo.getThreadName());
        System.out.println("Thread State: " + threadInfo.getThreadState());
        
        // 阻塞信息
        System.out.println("Blocked Count: " + threadInfo.getBlockedCount());
        System.out.println("Blocked Time: " + threadInfo.getBlockedTime() + "ms");
        
        // 等待信息
        System.out.println("Waited Count: " + threadInfo.getWaitedCount());
        System.out.println("Waited Time: " + threadInfo.getWaitedTime() + "ms");
        
        // 锁信息
        if (threadInfo.getLockName() != null) {
            System.out.println("Lock Name: " + threadInfo.getLockName());
            System.out.println("Lock Owner: " + threadInfo.getLockOwnerName());
            System.out.println("Lock Owner ID: " + threadInfo.getLockOwnerId());
        }
        
        // 栈跟踪
        System.out.println("\nStack Trace:");
        StackTraceElement[] stackTrace = threadInfo.getStackTrace();
        for (int i = 0; i < Math.min(stackTrace.length, 10); i++) {
            System.out.println("  " + stackTrace[i]);
        }
        
        if (stackTrace.length > 10) {
            System.out.println("  ... (" + (stackTrace.length - 10) + " more frames)");
        }
        
        // 锁信息详细分析
        MonitorInfo[] monitors = threadInfo.getLockedMonitors();
        if (monitors.length > 0) {
            System.out.println("\nLocked Monitors:");
            for (MonitorInfo monitor : monitors) {
                System.out.println("  " + monitor.getClassName() + "@" + 
                    Integer.toHexString(monitor.getIdentityHashCode()));
                System.out.println("    at " + monitor.getLockedStackFrame());
            }
        }
        
        LockInfo[] locks = threadInfo.getLockedSynchronizers();
        if (locks.length > 0) {
            System.out.println("\nLocked Synchronizers:");
            for (LockInfo lock : locks) {
                System.out.println("  " + lock.getClassName() + "@" + 
                    Integer.toHexString(lock.getIdentityHashCode()));
            }
        }
    }
    
    public static void analyzeAllThreads() {
        long[] threadIds = threadBean.getAllThreadIds();
        
        System.out.println("=== All Threads Analysis ===");
        System.out.println("Total threads: " + threadIds.length);
        System.out.println();
        
        for (long threadId : threadIds) {
            analyzeThread(threadId);
            System.out.println("\n" + "=".repeat(50) + "\n");
        }
    }
    
    public static void main(String[] args) {
        // 分析所有线程
        analyzeAllThreads();
    }
}
2.3.2 栈跟踪分析
// 栈跟踪分析工具
public class StackTraceAnalyzer {
    
    public static class StackAnalysisResult {
        public final String threadName;
        public final Thread.State state;
        public final String topMethod;
        public final String blockingResource;
        public final int stackDepth;
        public final boolean isInNativeMethod;
        public final boolean isInSystemCode;
        
        public StackAnalysisResult(ThreadInfo threadInfo) {
            this.threadName = threadInfo.getThreadName();
            this.state = threadInfo.getThreadState();
            
            StackTraceElement[] stack = threadInfo.getStackTrace();
            this.stackDepth = stack.length;
            
            if (stack.length > 0) {
                StackTraceElement top = stack[0];
                this.topMethod = top.getClassName() + "." + top.getMethodName();
                this.isInNativeMethod = top.isNativeMethod();
                this.isInSystemCode = isSystemCode(top.getClassName());
            } else {
                this.topMethod = "<empty stack>";
                this.isInNativeMethod = false;
                this.isInSystemCode = false;
            }
            
            this.blockingResource = threadInfo.getLockName();
        }
        
        private boolean isSystemCode(String className) {
            return className.startsWith("java.") || 
                   className.startsWith("javax.") ||
                   className.startsWith("sun.") ||
                   className.startsWith("com.sun.");
        }
        
        public String getAnalysis() {
            StringBuilder analysis = new StringBuilder();
            analysis.append(String.format("Thread: %s [%s]\n", threadName, state));
            analysis.append(String.format("Top Method: %s\n", topMethod));
            analysis.append(String.format("Stack Depth: %d\n", stackDepth));
            
            if (isInNativeMethod) {
                analysis.append("⚠️  Currently in native method\n");
            }
            
            if (isInSystemCode) {
                analysis.append("ℹ️  Currently in system code\n");
            }
            
            if (blockingResource != null) {
                analysis.append(String.format("🔒 Blocked on: %s\n", blockingResource));
            }
            
            // 状态特定分析
            switch (state) {
                case BLOCKED:
                    analysis.append("🚫 Thread is blocked waiting for a lock\n");
                    break;
                case WAITING:
                    analysis.append("⏳ Thread is waiting indefinitely\n");
                    break;
                case TIMED_WAITING:
                    analysis.append("⏰ Thread is waiting for a specified time\n");
                    break;
                case RUNNABLE:
                    if (isInNativeMethod) {
                        analysis.append("🔧 Thread may be doing I/O or native operations\n");
                    } else {
                        analysis.append("✅ Thread is actively running\n");
                    }
                    break;
            }
            
            return analysis.toString();
        }
    }
    
    public static void analyzeAllThreadStacks() {
        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
        long[] threadIds = threadBean.getAllThreadIds();
        ThreadInfo[] threadInfos = threadBean.getThreadInfo(threadIds, Integer.MAX_VALUE);
        
        System.out.println("=== Stack Trace Analysis ===");
        
        for (ThreadInfo threadInfo : threadInfos) {
            if (threadInfo != null) {
                StackAnalysisResult result = new StackAnalysisResult(threadInfo);
                System.out.println(result.getAnalysis());
                System.out.println("-".repeat(40));
            }
        }
    }
    
    public static void main(String[] args) {
        // 创建一些测试线程
        createTestScenarios();
        
        // 等待线程启动
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        // 分析栈跟踪
        analyzeAllThreadStacks();
    }
    
    private static void createTestScenarios() {
        // 场景1:IO等待
        new Thread(() -> {
            try {
                java.net.ServerSocket server = new java.net.ServerSocket(0);
                server.accept(); // 阻塞在IO操作
            } catch (Exception e) {
                // 忽略异常
            }
        }, "IO-Waiting-Thread").start();
        
        // 场景2:锁等待
        Object lock = new Object();
        new Thread(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }, "Lock-Holder-Thread").start();
        
        new Thread(() -> {
            synchronized (lock) {
                System.out.println("Got lock");
            }
        }, "Lock-Waiter-Thread").start();
        
        // 场景3:计算密集型
        new Thread(() -> {
            while (true) {
                Math.sqrt(Math.random());
            }
        }, "CPU-Intensive-Thread").start();
    }
}

3. 死锁检测

3.1 死锁基础理论

3.1.1 死锁的四个必要条件
  1. 互斥条件:资源不能被多个线程同时使用
  2. 持有和等待条件:线程持有资源的同时等待其他资源
  3. 不可剥夺条件:资源不能被强制从线程中剥夺
  4. 循环等待条件:存在线程资源的循环等待链
3.1.2 常见死锁模式

经典死锁示例

// 经典的两个锁死锁
public class ClassicDeadlock {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();
    
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread 1: Holding lock 1...");
                
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                System.out.println("Thread 1: Waiting for lock 2...");
                synchronized (lock2) {
                    System.out.println("Thread 1: Holding lock 1 & 2...");
                }
            }
        }, "DeadLock-Thread-1");
        
        Thread thread2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Thread 2: Holding lock 2...");
                
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                System.out.println("Thread 2: Waiting for lock 1...");
                synchronized (lock1) {
                    System.out.println("Thread 2: Holding lock 1 & 2...");
                }
            }
        }, "DeadLock-Thread-2");
        
        thread1.start();
        thread2.start();
        
        // 等待死锁发生
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        // 检测死锁
        detectDeadlock();
    }
    
    private static void detectDeadlock() {
        ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
        long[] deadlockedThreads = threadBean.findDeadlockedThreads();
        
        if (deadlockedThreads != null) {
            System.out.println("\n🚨 DEADLOCK DETECTED! 🚨");
            System.out.println("Deadlocked threads: " + deadlockedThreads.length);
            
            ThreadInfo[] threadInfos = threadBean.getThreadInfo(deadlockedThreads);
            for (ThreadInfo threadInfo : threadInfos) {
                System.out.println("\nThread: " + threadInfo.getThreadName());
                System.out.println("State: " + threadInfo.getThreadState());
                System.out.println("Blocked on: " + threadInfo.getLockName());
                System.out.println("Blocked by: " + threadInfo.getLockOwnerName());
            }
        } else {
            System.out.println("No deadlock detected.");
        }
    }
}

复杂死锁示例

// 多线程多锁死锁
public class ComplexDeadlock {
    private static final Object lockA = new Object();
    private static final Object lockB = new Object();
    private static final Object lockC = new Object();
    
    public static void main(String[] args) {
        // 创建循环等待:Thread1 → A → B, Thread2 → B → C, Thread3 → C → A
        
        Thread thread1 = new Thread(() -> {
            synchronized (lockA) {
                System.out.println("Thread 1: Got lock A");
                sleep(100);
                synchronized (lockB) {
                    System.out.println("Thread 1: Got lock B");
                }
            }
        }, "Complex-DeadLock-Thread-1");
        
        Thread thread2 = new Thread(() -> {
            synchronized (lockB) {
                System.out.println("Thread 2: Got lock B");
                sleep(100);
                synchronized (lockC) {
                    System.out.println("Thread 2: Got lock C");
                }
            }
        }, "Complex-DeadLock-Thread-2");
        
        Thread thread3 = new Thread(() -> {
            synchronized (lockC) {
                System.out.println("Thread 3: Got lock C");
                sleep(100);
                synchronized (lockA) {
                    System.out.println("Thread 3: Got lock A");
                }
            }
        }, "Complex-DeadLock-Thread-3");
        
        thread1.start();
        thread2.start();
        thread3.start();
        
        // 等待死锁发生并检测
        sleep(1000);
        new DeadlockDetector().detectAndAnalyze();
    }
    
    private static void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

3.2 VisualVM 死锁检测

3.2.1 死锁检测界面

在 VisualVM 的 Threads 标签页中,当检测到死锁时会显示:

┌─────────────────────────────────────────────────────────────┐
│                    🚨 DEADLOCK DETECTED 🚨                  │
├─────────────────────────────────────────────────────────────┤
│  死锁线程列表:                                              │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ Thread Name           State      Blocked On              │ │
│  │ DeadLock-Thread-1     BLOCKED    java.lang.Object@abc123 │ │
│  │ DeadLock-Thread-2     BLOCKED    java.lang.Object@def456 │ │
│  └─────────────────────────────────────────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│  死锁循环链:                                                │
│  ┌─────────────────────────────────────────────────────────┐ │
│  │ DeadLock-Thread-1 → Object@abc123 → DeadLock-Thread-2   │ │
│  │ DeadLock-Thread-2 → Object@def456 → DeadLock-Thread-1   │ │
│  └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
3.2.2 死锁分析工具
// 高级死锁检测和分析工具
import java.lang.management.*;
import java.util.*;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class DeadlockDetector {
    private static final ThreadMXBean threadBean = 
        ManagementFactory.getThreadMXBean();
    private final ScheduledExecutorService scheduler = 
        Executors.newScheduledThreadPool(1);
    
    public static class DeadlockInfo {
        public final long[] deadlockedThreadIds;
        public final ThreadInfo[] deadlockedThreadInfos;
        public final Map<Long, String> threadNames;
        public final Map<Long, String> lockChain;
        public final long detectionTime;
        
        public DeadlockInfo(long[] threadIds, ThreadInfo[] threadInfos) {
            this.deadlockedThreadIds = threadIds;
            this.deadlockedThreadInfos = threadInfos;
            this.detectionTime = System.currentTimeMillis();
            this.threadNames = new HashMap<>();
            this.lockChain = new HashMap<>();
            
            // 构建线程名映射和锁链
            for (ThreadInfo info : threadInfos) {
                threadNames.put(info.getThreadId(), info.getThreadName());
                if (info.getLockOwnerId() != -1) {
                    lockChain.put(info.getThreadId(), 
                        threadNames.get(info.getLockOwnerId()));
                }
            }
        }
        
        public void printAnalysis() {
            System.out.println("\n🚨 ===== DEADLOCK ANALYSIS ===== 🚨");
            System.out.println("Detection Time: " + new Date(detectionTime));
            System.out.println("Deadlocked Threads: " + deadlockedThreadIds.length);
            System.out.println();
            
            // 打印每个死锁线程的详细信息
            for (ThreadInfo info : deadlockedThreadInfos) {
                printThreadDeadlockInfo(info);
                System.out.println();
            }
            
            // 打印死锁循环链
            printDeadlockCycle();
            
            // 提供解决建议
            printResolutionSuggestions();
        }
        
        private void printThreadDeadlockInfo(ThreadInfo info) {
            System.out.println("Thread: " + info.getThreadName() + 
                " (ID: " + info.getThreadId() + ")");
            System.out.println("State: " + info.getThreadState());
            System.out.println("Blocked on: " + info.getLockName());
            System.out.println("Lock owner: " + info.getLockOwnerName() + 
                " (ID: " + info.getLockOwnerId() + ")");
            
            // 打印关键栈帧
            StackTraceElement[] stack = info.getStackTrace();
            System.out.println("Key stack frames:");
            for (int i = 0; i < Math.min(stack.length, 5); i++) {
                StackTraceElement frame = stack[i];
                System.out.println("  at " + frame);
                
                // 标记同步块
                if (frame.getMethodName().contains("synchronized") ||
                    (i < stack.length - 1 && 
                     stack[i + 1].getMethodName().contains("synchronized"))) {
                    System.out.println("    ^ Synchronization point");
                }
            }
        }
        
        private void printDeadlockCycle() {
            System.out.println("🔄 Deadlock Cycle:");
            
            // 构建循环链
            Set<Long> visited = new HashSet<>();
            for (long threadId : deadlockedThreadIds) {
                if (!visited.contains(threadId)) {
                    List<String> cycle = buildCycle(threadId, visited);
                    if (cycle.size() > 1) {
                        System.out.println("  " + String.join(" → ", cycle) + 
                            " → " + cycle.get(0));
                    }
                }
            }
        }
        
        private List<String> buildCycle(long startThreadId, Set<Long> visited) {
            List<String> cycle = new ArrayList<>();
            long currentThreadId = startThreadId;
            
            while (!visited.contains(currentThreadId)) {
                visited.add(currentThreadId);
                String threadName = threadNames.get(currentThreadId);
                cycle.add(threadName);
                
                // 找到这个线程等待的锁的拥有者
                ThreadInfo info = null;
                for (ThreadInfo ti : deadlockedThreadInfos) {
                    if (ti.getThreadId() == currentThreadId) {
                        info = ti;
                        break;
                    }
                }
                
                if (info != null && info.getLockOwnerId() != -1) {
                    currentThreadId = info.getLockOwnerId();
                } else {
                    break;
                }
            }
            
            return cycle;
        }
        
        private void printResolutionSuggestions() {
            System.out.println("💡 Resolution Suggestions:");
            System.out.println("1. 🔄 Restart the application to break the deadlock");
            System.out.println("2. 📋 Review lock acquisition order in the code");
            System.out.println("3. ⏱️  Consider using timeout-based locking");
            System.out.println("4. 🔧 Implement lock ordering to prevent future deadlocks");
            System.out.println("5. 🧪 Use java.util.concurrent utilities instead of synchronized");
            
            // 分析锁的获取模式
            analyzeLockPatterns();
        }
        
        private void analyzeLockPatterns() {
            System.out.println("\n🔍 Lock Pattern Analysis:");
            
            Map<String, Integer> lockTypes = new HashMap<>();
            Map<String, Integer> methodPatterns = new HashMap<>();
            
            for (ThreadInfo info : deadlockedThreadInfos) {
                // 分析锁类型
                String lockName = info.getLockName();
                if (lockName != null) {
                    String lockType = lockName.substring(0, lockName.indexOf('@'));
                    lockTypes.put(lockType, lockTypes.getOrDefault(lockType, 0) + 1);
                }
                
                // 分析方法模式
                StackTraceElement[] stack = info.getStackTrace();
                for (StackTraceElement frame : stack) {
                    String method = frame.getClassName() + "." + frame.getMethodName();
                    if (!method.startsWith("java.") && !method.startsWith("sun.")) {
                        methodPatterns.put(method, 
                            methodPatterns.getOrDefault(method, 0) + 1);
                        break; // 只记录第一个非系统方法
                    }
                }
            }
            
            System.out.println("Lock types involved:");
            lockTypes.forEach((type, count) -> 
                System.out.println("  " + type + ": " + count + " threads"));
            
            System.out.println("Methods involved:");
            methodPatterns.forEach((method, count) -> 
                System.out.println("  " + method + ": " + count + " threads"));
        }
    }
    
    public DeadlockInfo detectDeadlock() {
        long[] deadlockedThreads = threadBean.findDeadlockedThreads();
        
        if (deadlockedThreads != null && deadlockedThreads.length > 0) {
            ThreadInfo[] threadInfos = threadBean.getThreadInfo(deadlockedThreads);
            return new DeadlockInfo(deadlockedThreads, threadInfos);
        }
        
        return null;
    }
    
    public void detectAndAnalyze() {
        DeadlockInfo deadlockInfo = detectDeadlock();
        
        if (deadlockInfo != null) {
            deadlockInfo.printAnalysis();
        } else {
            System.out.println("✅ No deadlock detected.");
        }
    }
    
    public void startContinuousMonitoring(int intervalSeconds) {
        System.out.println("🔍 Starting continuous deadlock monitoring...");
        System.out.println("Check interval: " + intervalSeconds + " seconds");
        
        scheduler.scheduleAtFixedRate(() -> {
            DeadlockInfo deadlockInfo = detectDeadlock();
            if (deadlockInfo != null) {
                System.out.println("\n⚠️  DEADLOCK DETECTED AT " + new Date());
                deadlockInfo.printAnalysis();
                
                // 可以在这里添加告警逻辑
                sendDeadlockAlert(deadlockInfo);
            }
        }, 0, intervalSeconds, TimeUnit.SECONDS);
    }
    
    private void sendDeadlockAlert(DeadlockInfo deadlockInfo) {
        // 这里可以实现告警逻辑,比如:
        // - 发送邮件
        // - 写入日志文件
        // - 调用监控系统API
        // - 生成堆转储文件
        
        System.out.println("📧 Deadlock alert sent!");
        
        // 示例:生成线程转储文件
        generateThreadDump(deadlockInfo);
    }
    
    private void generateThreadDump(DeadlockInfo deadlockInfo) {
        try {
            String timestamp = String.valueOf(System.currentTimeMillis());
            String filename = "deadlock_thread_dump_" + timestamp + ".txt";
            
            try (java.io.PrintWriter writer = new java.io.PrintWriter(
                    new java.io.FileWriter(filename))) {
                
                writer.println("Deadlock Thread Dump");
                writer.println("Generated at: " + new Date(deadlockInfo.detectionTime));
                writer.println("=".repeat(50));
                
                // 写入所有线程信息
                long[] allThreadIds = threadBean.getAllThreadIds();
                ThreadInfo[] allThreadInfos = threadBean.getThreadInfo(
                    allThreadIds, Integer.MAX_VALUE);
                
                for (ThreadInfo info : allThreadInfos) {
                    if (info != null) {
                        writer.println("\nThread: " + info.getThreadName());
                        writer.println("State: " + info.getThreadState());
                        
                        if (info.getLockName() != null) {
                            writer.println("Blocked on: " + info.getLockName());
                        }
                        
                        writer.println("Stack trace:");
                        for (StackTraceElement frame : info.getStackTrace()) {
                            writer.println("  at " + frame);
                        }
                        writer.println();
                    }
                }
            }
            
            System.out.println("📄 Thread dump saved to: " + filename);
            
        } catch (java.io.IOException e) {
            System.err.println("Failed to generate thread dump: " + e.getMessage());
        }
    }
    
    public void shutdown() {
        scheduler.shutdown();
    }
    
    public static void main(String[] args) {
        DeadlockDetector detector = new DeadlockDetector();
        
        // 立即检测一次
        detector.detectAndAnalyze();
        
        // 启动连续监控
        detector.startContinuousMonitoring(10);
        
        // 保持程序运行
        try {
            Thread.sleep(Long.MAX_VALUE);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            detector.shutdown();
        }
    }
}

3.3 死锁预防和解决

3.3.1 死锁预防策略

锁排序策略

// 通过锁排序避免死锁
public class DeadlockPrevention {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();
    
    // 为锁分配唯一的ID
    private static final int LOCK1_ID = System.identityHashCode(lock1);
    private static final int LOCK2_ID = System.identityHashCode(lock2);
    
    // 安全的双锁方法
    public static void safeDoublelock(Runnable task) {
        Object firstLock, secondLock;
        
        // 总是按照相同的顺序获取锁
        if (LOCK1_ID < LOCK2_ID) {
            firstLock = lock1;
            secondLock = lock2;
        } else {
            firstLock = lock2;
            secondLock = lock1;
        }
        
        synchronized (firstLock) {
            synchronized (secondLock) {
                task.run();
            }
        }
    }
    
    public static void main(String[] args) {
        // 两个线程都使用相同的锁顺序,避免死锁
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                safeDoublelock(() -> {
                    System.out.println("Thread 1: iteration " + i);
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            }
        }, "Safe-Thread-1");
        
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 100; i++) {
                safeDoublelock(() -> {
                    System.out.println("Thread 2: iteration " + i);
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            }
        }, "Safe-Thread-2");
        
        thread1.start();
        thread2.start();
        
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        System.out.println("✅ Completed without deadlock!");
    }
}

超时锁策略

// 使用超时避免死锁
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.TimeUnit;

public class TimeoutLockStrategy {
    private static final ReentrantLock lock1 = new ReentrantLock();
    private static final ReentrantLock lock2 = new ReentrantLock();
    private static final int TIMEOUT_MS = 1000;
    
    public static boolean tryDoublelock(Runnable task) {
        boolean lock1Acquired = false;
        boolean lock2Acquired = false;
        
        try {
            // 尝试获取第一个锁
            lock1Acquired = lock1.tryLock(TIMEOUT_MS, TimeUnit.MILLISECONDS);
            if (!lock1Acquired) {
                System.out.println("Failed to acquire lock1 within timeout");
                return false;
            }
            
            // 尝试获取第二个锁
            lock2Acquired = lock2.tryLock(TIMEOUT_MS, TimeUnit.MILLISECONDS);
            if (!lock2Acquired) {
                System.out.println("Failed to acquire lock2 within timeout");
                return false;
            }
            
            // 执行任务
            task.run();
            return true;
            
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        } finally {
            // 释放锁(按相反顺序)
            if (lock2Acquired) {
                lock2.unlock();
            }
            if (lock1Acquired) {
                lock1.unlock();
            }
        }
    }
    
    public static void main(String[] args) {
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                boolean success = tryDoublelock(() -> {
                    System.out.println("Thread 1: Got both locks, iteration " + i);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
                
                if (!success) {
                    System.out.println("Thread 1: Failed to get locks, retrying...");
                    try {
                        Thread.sleep(50); // 短暂等待后重试
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }, "Timeout-Thread-1");
        
        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                boolean success = tryDoublelock(() -> {
                    System.out.println("Thread 2: Got both locks, iteration " + i);
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
                
                if (!success) {
                    System.out.println("Thread 2: Failed to get locks, retrying...");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }, "Timeout-Thread-2");
        
        thread1.start();
        thread2.start();
        
        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        System.out.println("✅ Completed with timeout-based locking!");
    }
}

4. 线程转储分析

4.1 生成线程转储

4.1.1 通过 VisualVM 生成

在 VisualVM 中生成线程转储:

  1. 右键点击应用程序
  2. 选择 “Thread Dump”
  3. 线程转储会在新标签页中打开
4.1.2 通过命令行生成
# 使用 jstack 生成线程转储
jstack <PID> > thread_dump.txt

# 使用 kill 信号生成(Linux/macOS)
kill -3 <PID>

# 使用 JVM 参数在 OOM 时自动生成
java -XX:+PrintGCDetails \
     -XX:+HeapDumpOnOutOfMemoryError \
     -XX:+PrintConcurrentLocks \
     YourApplication
4.1.3 程序化生成
// 程序化生成线程转储
import java.lang.management.*;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class ThreadDumpGenerator {
    private static final ThreadMXBean threadBean = 
        ManagementFactory.getThreadMXBean();
    
    public static void generateThreadDump(String filename) {
        try (PrintWriter writer = new PrintWriter(new FileWriter(filename))) {
            writer.println("Thread Dump");
            writer.println("Generated at: " + LocalDateTime.now());
            writer.println("JVM: " + System.getProperty("java.vm.name") + 
                " " + System.getProperty("java.vm.version"));
            writer.println("=".repeat(80));
            writer.println();
            
            // 获取所有线程信息
            long[] threadIds = threadBean.getAllThreadIds();
            ThreadInfo[] threadInfos = threadBean.getThreadInfo(
                threadIds, Integer.MAX_VALUE);
            
            // 检查死锁
            long[] deadlockedThreads = threadBean.findDeadlockedThreads();
            if (deadlockedThreads != null) {
                writer.println("🚨 DEADLOCK DETECTED!");
                writer.println("Deadlocked threads: " + deadlockedThreads.length);
                writer.println();
            }
            
            // 写入每个线程的详细信息
            for (ThreadInfo threadInfo : threadInfos) {
                if (threadInfo != null) {
                    writeThreadInfo(writer, threadInfo, deadlockedThreads);
                    writer.println();
                }
            }
            
            System.out.println("Thread dump generated: " + filename);
            
        } catch (IOException e) {
            System.err.println("Failed to generate thread dump: " + e.getMessage());
        }
    }
    
    private static void writeThreadInfo(PrintWriter writer, ThreadInfo threadInfo, 
                                       long[] deadlockedThreads) {
        boolean isDeadlocked = deadlockedThreads != null && 
            java.util.Arrays.stream(deadlockedThreads)
                .anyMatch(id -> id == threadInfo.getThreadId());
        
        writer.println("Thread: " + threadInfo.getThreadName() + 
            (isDeadlocked ? " [DEADLOCKED]" : ""));
        writer.println("ID: " + threadInfo.getThreadId());
        writer.println("State: " + threadInfo.getThreadState());
        
        if (threadInfo.getLockName() != null) {
            writer.println("Blocked on: " + threadInfo.getLockName());
            writer.println("Lock owner: " + threadInfo.getLockOwnerName() + 
                " (ID: " + threadInfo.getLockOwnerId() + ")");
        }
        
        writer.println("Blocked count: " + threadInfo.getBlockedCount());
        writer.println("Waited count: " + threadInfo.getWaitedCount());
        
        // 栈跟踪
        writer.println("Stack trace:");
        StackTraceElement[] stackTrace = threadInfo.getStackTrace();
        for (StackTraceElement frame : stackTrace) {
            writer.println("  at " + frame);
        }
        
        // 锁信息
        MonitorInfo[] monitors = threadInfo.getLockedMonitors();
        if (monitors.length > 0) {
            writer.println("Locked monitors:");
            for (MonitorInfo monitor : monitors) {
                writer.println("  " + monitor.getClassName() + "@" + 
                    Integer.toHexString(monitor.getIdentityHashCode()));
            }
        }
        
        LockInfo[] locks = threadInfo.getLockedSynchronizers();
        if (locks.length > 0) {
            writer.println("Locked synchronizers:");
            for (LockInfo lock : locks) {
                writer.println("  " + lock.getClassName() + "@" + 
                    Integer.toHexString(lock.getIdentityHashCode()));
            }
        }
    }
    
    public static void main(String[] args) {
        String timestamp = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")
            .format(LocalDateTime.now());
        String filename = "thread_dump_" + timestamp + ".txt";
        
        generateThreadDump(filename);
    }
}

4.2 线程转储分析

4.2.1 转储文件结构

典型的线程转储文件结构:

Thread Dump
Generated at: 2024-01-15T10:30:45
JVM: OpenJDK 64-Bit Server VM 11.0.16
================================================================================

🚨 DEADLOCK DETECTED!
Deadlocked threads: 2

Thread: DeadLock-Thread-1 [DEADLOCKED]
ID: 12
State: BLOCKED
Blocked on: java.lang.Object@1a2b3c4d
Lock owner: DeadLock-Thread-2 (ID: 13)
Blocked count: 1
Waited count: 0
Stack trace:
  at java.lang.Object.wait(Native Method)
  at java.lang.Object.wait(Object.java:502)
  at com.example.DeadlockExample.method1(DeadlockExample.java:25)
  at com.example.DeadlockExample.lambda$main$0(DeadlockExample.java:15)
  at java.lang.Thread.run(Thread.java:748)

Thread: DeadLock-Thread-2 [DEADLOCKED]
ID: 13
State: BLOCKED
Blocked on: java.lang.Object@5e6f7a8b
Lock owner: DeadLock-Thread-1 (ID: 12)
Blocked count: 1
Waited count: 0
Stack trace:
  at java.lang.Object.wait(Native Method)
  at java.lang.Object.wait(Object.java:502)
  at com.example.DeadlockExample.method2(DeadlockExample.java:35)
  at com.example.DeadlockExample.lambda$main$1(DeadlockExample.java:20)
  at java.lang.Thread.run(Thread.java:748)
4.2.2 自动化分析工具
// 线程转储自动分析工具
import java.io.*;
import java.util.*;
import java.util.regex.*;

public class ThreadDumpAnalyzer {
    
    public static class AnalysisResult {
        public int totalThreads;
        public Map<Thread.State, Integer> threadsByState;
        public List<String> deadlockedThreads;
        public Map<String, Integer> blockedOnResources;
        public Map<String, Integer> topStackFrames;
        public List<String> suspiciousPatterns;
        public Map<String, Integer> threadNamePatterns;
        
        public AnalysisResult() {
            threadsByState = new EnumMap<>(Thread.State.class);
            deadlockedThreads = new ArrayList<>();
            blockedOnResources = new HashMap<>();
            topStackFrames = new HashMap<>();
            suspiciousPatterns = new ArrayList<>();
            threadNamePatterns = new HashMap<>();
        }
        
        public void printSummary() {
            System.out.println("=== Thread Dump Analysis Summary ===");
            System.out.println("Total threads: " + totalThreads);
            
            System.out.println("\nThreads by state:");
            threadsByState.forEach((state, count) -> 
                System.out.println("  " + state + ": " + count));
            
            if (!deadlockedThreads.isEmpty()) {
                System.out.println("\n🚨 Deadlocked threads:");
                deadlockedThreads.forEach(thread -> 
                    System.out.println("  " + thread));
            }
            
            if (!blockedOnResources.isEmpty()) {
                System.out.println("\n🔒 Most contended resources:");
                blockedOnResources.entrySet().stream()
                    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                    .limit(5)
                    .forEach(entry -> 
                        System.out.println("  " + entry.getKey() + ": " + 
                            entry.getValue() + " threads"));
            }
            
            if (!topStackFrames.isEmpty()) {
                System.out.println("\n📊 Top stack frames:");
                topStackFrames.entrySet().stream()
                    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                    .limit(10)
                    .forEach(entry -> 
                        System.out.println("  " + entry.getKey() + ": " + 
                            entry.getValue() + " threads"));
            }
            
            if (!suspiciousPatterns.isEmpty()) {
                System.out.println("\n⚠️  Suspicious patterns detected:");
                suspiciousPatterns.forEach(pattern -> 
                    System.out.println("  " + pattern));
            }
            
            if (!threadNamePatterns.isEmpty()) {
                System.out.println("\n🏷️  Thread name patterns:");
                threadNamePatterns.entrySet().stream()
                    .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                    .forEach(entry -> 
                        System.out.println("  " + entry.getKey() + ": " + 
                            entry.getValue() + " threads"));
            }
        }
    }
    
    public static AnalysisResult analyzeThreadDump(String filename) {
        AnalysisResult result = new AnalysisResult();
        
        try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
            String line;
            String currentThread = null;
            Thread.State currentState = null;
            List<String> currentStackTrace = new ArrayList<>();
            
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                
                // 解析线程信息
                if (line.startsWith("Thread: ")) {
                    // 处理前一个线程的信息
                    if (currentThread != null) {
                        processThreadInfo(result, currentThread, currentState, currentStackTrace);
                    }
                    
                    // 开始新线程
                    currentThread = extractThreadName(line);
                    currentStackTrace.clear();
                    result.totalThreads++;
                    
                    // 检查是否是死锁线程
                    if (line.contains("[DEADLOCKED]")) {
                        result.deadlockedThreads.add(currentThread);
                    }
                    
                } else if (line.startsWith("State: ")) {
                    currentState = parseThreadState(line);
                    if (currentState != null) {
                        result.threadsByState.put(currentState, 
                            result.threadsByState.getOrDefault(currentState, 0) + 1);
                    }
                    
                } else if (line.startsWith("Blocked on: ")) {
                    String resource = extractResource(line);
                    if (resource != null) {
                        result.blockedOnResources.put(resource, 
                            result.blockedOnResources.getOrDefault(resource, 0) + 1);
                    }
                    
                } else if (line.startsWith("  at ")) {
                    currentStackTrace.add(line.substring(5)); // 移除 "  at "
                    
                    // 记录栈帧
                    String method = extractMethodFromStackFrame(line);
                    if (method != null && !isSystemMethod(method)) {
                        result.topStackFrames.put(method, 
                            result.topStackFrames.getOrDefault(method, 0) + 1);
                    }
                }
            }
            
            // 处理最后一个线程
            if (currentThread != null) {
                processThreadInfo(result, currentThread, currentState, currentStackTrace);
            }
            
        } catch (IOException e) {
            System.err.println("Error reading thread dump file: " + e.getMessage());
        }
        
        // 检测可疑模式
        detectSuspiciousPatterns(result);
        
        return result;
    }
    
    private static void processThreadInfo(AnalysisResult result, String threadName, 
                                        Thread.State state, List<String> stackTrace) {
        // 分析线程名模式
        String pattern = extractThreadNamePattern(threadName);
        result.threadNamePatterns.put(pattern, 
            result.threadNamePatterns.getOrDefault(pattern, 0) + 1);
    }
    
    private static String extractThreadName(String line) {
        // 提取 "Thread: name [DEADLOCKED]" 中的 name
        Pattern pattern = Pattern.compile("Thread: ([^\\[]+)");
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            return matcher.group(1).trim();
        }
        return "Unknown";
    }
    
    private static Thread.State parseThreadState(String line) {
        String stateStr = line.substring("State: ".length()).trim();
        try {
            return Thread.State.valueOf(stateStr);
        } catch (IllegalArgumentException e) {
            return null;
        }
    }
    
    private static String extractResource(String line) {
        // 提取 "Blocked on: java.lang.Object@1a2b3c4d" 中的资源类型
        String resource = line.substring("Blocked on: ".length()).trim();
        int atIndex = resource.indexOf('@');
        if (atIndex > 0) {
            return resource.substring(0, atIndex);
        }
        return resource;
    }
    
    private static String extractMethodFromStackFrame(String line) {
        // 提取 "  at com.example.Class.method(Class.java:123)" 中的方法
        String frame = line.substring(5).trim(); // 移除 "  at "
        int parenIndex = frame.indexOf('(');
        if (parenIndex > 0) {
            return frame.substring(0, parenIndex);
        }
        return frame;
    }
    
    private static boolean isSystemMethod(String method) {
        return method.startsWith("java.") || 
               method.startsWith("javax.") ||
               method.startsWith("sun.") ||
               method.startsWith("com.sun.");
    }
    
    private static String extractThreadNamePattern(String threadName) {
        // 提取线程名模式,如 "pool-1-thread-123" -> "pool-*-thread-*"
        return threadName.replaceAll("\\d+", "*");
    }
    
    private static void detectSuspiciousPatterns(AnalysisResult result) {
        // 检测大量BLOCKED线程
        int blockedCount = result.threadsByState.getOrDefault(Thread.State.BLOCKED, 0);
        if (blockedCount > result.totalThreads * 0.3) {
            result.suspiciousPatterns.add(
                String.format("High number of BLOCKED threads: %d (%.1f%%)", 
                    blockedCount, (double)blockedCount / result.totalThreads * 100));
        }
        
        // 检测大量WAITING线程
        int waitingCount = result.threadsByState.getOrDefault(Thread.State.WAITING, 0);
        if (waitingCount > result.totalThreads * 0.5) {
            result.suspiciousPatterns.add(
                String.format("High number of WAITING threads: %d (%.1f%%)", 
                    waitingCount, (double)waitingCount / result.totalThreads * 100));
        }
        
        // 检测线程池饱和
        for (Map.Entry<String, Integer> entry : result.threadNamePatterns.entrySet()) {
            if (entry.getKey().contains("pool") && entry.getValue() > 50) {
                result.suspiciousPatterns.add(
                    String.format("Large thread pool detected: %s (%d threads)", 
                        entry.getKey(), entry.getValue()));
            }
        }
        
        // 检测热点资源
        for (Map.Entry<String, Integer> entry : result.blockedOnResources.entrySet()) {
            if (entry.getValue() > 10) {
                result.suspiciousPatterns.add(
                    String.format("Resource contention hotspot: %s (%d threads blocked)", 
                        entry.getKey(), entry.getValue()));
            }
        }
    }
    
    public static void main(String[] args) {
        if (args.length != 1) {
            System.out.println("Usage: java ThreadDumpAnalyzer <thread_dump_file>");
            return;
        }
        
        String filename = args[0];
        AnalysisResult result = analyzeThreadDump(filename);
        result.printSummary();
    }
}

5. 实践练习

5.1 练习1:线程状态监控

目标:创建一个多线程应用,观察不同线程状态的变化。

// 线程状态监控练习
public class ThreadStateMonitoringExercise {
    private static final Object sharedLock = new Object();
    private static volatile boolean running = true;
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Thread State Monitoring Exercise ===");
        System.out.println("启动多个不同状态的线程,使用 VisualVM 观察线程状态变化");
        
        // 1. RUNNABLE 状态线程(CPU密集型)
        Thread cpuIntensive = new Thread(() -> {
            while (running) {
                // 执行计算密集型任务
                double result = 0;
                for (int i = 0; i < 100000; i++) {
                    result += Math.sqrt(i);
                }
            }
        }, "CPU-Intensive-Thread");
        
        // 2. TIMED_WAITING 状态线程
        Thread sleepingThread = new Thread(() -> {
            while (running) {
                try {
                    Thread.sleep(2000);
                    System.out.println("Sleeping thread woke up");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "Sleeping-Thread");
        
        // 3. WAITING 状态线程
        Thread waitingThread = new Thread(() -> {
            synchronized (sharedLock) {
                try {
                    while (running) {
                        sharedLock.wait();
                        System.out.println("Waiting thread was notified");
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }, "Waiting-Thread");
        
        // 4. BLOCKED 状态线程
        Thread blockedThread1 = new Thread(() -> {
            while (running) {
                synchronized (sharedLock) {
                    try {
                        Thread.sleep(1000);
                        System.out.println("Blocked thread 1 holding lock");
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "Blocked-Thread-1");
        
        Thread blockedThread2 = new Thread(() -> {
            while (running) {
                synchronized (sharedLock) {
                    try {
                        Thread.sleep(1000);
                        System.out.println("Blocked thread 2 holding lock");
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "Blocked-Thread-2");
        
        // 启动所有线程
        cpuIntensive.start();
        sleepingThread.start();
        waitingThread.start();
        blockedThread1.start();
        blockedThread2.start();
        
        // 定期唤醒等待线程
        Thread notifierThread = new Thread(() -> {
            while (running) {
                try {
                    Thread.sleep(5000);
                    synchronized (sharedLock) {
                        sharedLock.notify();
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        }, "Notifier-Thread");
        notifierThread.start();
        
        System.out.println("\n线程已启动,请在 VisualVM 中观察线程状态:");
        System.out.println("1. 打开 VisualVM");
        System.out.println("2. 连接到当前 Java 进程");
        System.out.println("3. 切换到 Threads 标签页");
        System.out.println("4. 观察不同颜色的线程状态变化");
        System.out.println("\n按 Enter 键停止程序...");
        
        System.in.read();
        
        // 停止所有线程
        running = false;
        
        // 唤醒等待线程以便正常退出
        synchronized (sharedLock) {
            sharedLock.notifyAll();
        }
        
        // 等待所有线程结束
        cpuIntensive.interrupt();
        sleepingThread.interrupt();
        waitingThread.interrupt();
        blockedThread1.interrupt();
        blockedThread2.interrupt();
        notifierThread.interrupt();
        
        System.out.println("程序已停止");
    }
}

5.2 练习2:死锁检测与分析

目标:创建死锁场景,使用 VisualVM 检测和分析死锁。

// 死锁检测练习
public class DeadlockDetectionExercise {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();
    private static final Object lock3 = new Object();
    
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Deadlock Detection Exercise ===");
        System.out.println("创建死锁场景,使用 VisualVM 检测死锁");
        
        // 场景1:简单的两线程死锁
        createSimpleDeadlock();
        
        Thread.sleep(2000);
        
        // 场景2:复杂的三线程循环死锁
        createComplexDeadlock();
        
        System.out.println("\n死锁已创建,请在 VisualVM 中检测:");
        System.out.println("1. 在 Threads 标签页中查看死锁警告");
        System.out.println("2. 点击 'Thread Dump' 按钮生成线程转储");
        System.out.println("3. 分析死锁循环链");
        System.out.println("4. 查看每个死锁线程的栈跟踪");
        
        // 启动死锁监控
        DeadlockDetector detector = new DeadlockDetector();
        detector.startContinuousMonitoring(5);
        
        // 保持程序运行
        Thread.sleep(Long.MAX_VALUE);
    }
    
    private static void createSimpleDeadlock() {
        Thread thread1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Simple-Thread-1: Got lock1");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                System.out.println("Simple-Thread-1: Trying to get lock2...");
                synchronized (lock2) {
                    System.out.println("Simple-Thread-1: Got both locks");
                }
            }
        }, "Simple-Deadlock-Thread-1");
        
        Thread thread2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Simple-Thread-2: Got lock2");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                System.out.println("Simple-Thread-2: Trying to get lock1...");
                synchronized (lock1) {
                    System.out.println("Simple-Thread-2: Got both locks");
                }
            }
        }, "Simple-Deadlock-Thread-2");
        
        thread1.start();
        thread2.start();
    }
    
    private static void createComplexDeadlock() {
        Thread threadA = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Complex-Thread-A: Got lock1");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                synchronized (lock2) {
                    System.out.println("Complex-Thread-A: Got lock2");
                }
            }
        }, "Complex-Deadlock-Thread-A");
        
        Thread threadB = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Complex-Thread-B: Got lock2");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                synchronized (lock3) {
                    System.out.println("Complex-Thread-B: Got lock3");
                }
            }
        }, "Complex-Deadlock-Thread-B");
        
        Thread threadC = new Thread(() -> {
            synchronized (lock3) {
                System.out.println("Complex-Thread-C: Got lock3");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                
                synchronized (lock1) {
                    System.out.println("Complex-Thread-C: Got lock1");
                }
            }
        }, "Complex-Deadlock-Thread-C");
        
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

5.3 练习3:线程转储分析

目标:生成和分析线程转储文件。

// 线程转储分析练习
public class ThreadDumpAnalysisExercise {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("=== Thread Dump Analysis Exercise ===");
        
        // 创建各种线程场景
        createVariousThreadScenarios();
        
        // 等待线程启动
        Thread.sleep(2000);
        
        // 生成线程转储
        String dumpFile = "exercise_thread_dump.txt";
        ThreadDumpGenerator.generateThreadDump(dumpFile);
        
        // 分析线程转储
        System.out.println("\n分析线程转储文件...");
        ThreadDumpAnalyzer.AnalysisResult result = 
            ThreadDumpAnalyzer.analyzeThreadDump(dumpFile);
        result.printSummary();
        
        System.out.println("\n练习完成!请查看生成的线程转储文件: " + dumpFile);
    }
    
    private static void createVariousThreadScenarios() {
        // 创建多种线程场景用于分析
        
        // 1. 线程池场景
        java.util.concurrent.ExecutorService executor = 
            java.util.concurrent.Executors.newFixedThreadPool(10);
        
        for (int i = 0; i < 20; i++) {
            final int taskId = i;
            executor.submit(() -> {
                try {
                    Thread.sleep(10000 + (int)(Math.random() * 5000));
                    System.out.println("Task " + taskId + " completed");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        
        // 2. 生产者-消费者场景
        java.util.concurrent.BlockingQueue<String> queue = 
            new java.util.concurrent.ArrayBlockingQueue<>(5);
        
        // 生产者
        for (int i = 0; i < 3; i++) {
            final int producerId = i;
            new Thread(() -> {
                int count = 0;
                while (true) {
                    try {
                        queue.put("Item-" + producerId + "-" + (++count));
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }, "Producer-" + i).start();
        }
        
        // 消费者
        for (int i = 0; i < 2; i++) {
            final int consumerId = i;
            new Thread(() -> {
                while (true) {
                    try {
                        String item = queue.take();
                        Thread.sleep(200);
                        System.out.println("Consumer-" + consumerId + " processed: " + item);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }, "Consumer-" + i).start();
        }
        
        // 3. 锁竞争场景
        Object contentionLock = new Object();
        for (int i = 0; i < 5; i++) {
            final int threadId = i;
            new Thread(() -> {
                while (true) {
                    synchronized (contentionLock) {
                        try {
                            Thread.sleep(50);
                            // 模拟工作
                            for (int j = 0; j < 1000; j++) {
                                Math.sqrt(j);
                            }
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            break;
                        }
                    }
                    
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }, "Contention-Thread-" + i).start();
        }
    }
}

6. 本章总结

6.1 关键要点

  1. 线程状态理解

    • 掌握 Java 线程的六种状态及其转换条件
    • 理解每种状态在 VisualVM 中的颜色表示
    • 能够通过线程状态分析应用程序的行为模式
  2. VisualVM 线程监控

    • 熟练使用 Threads 标签页进行实时监控
    • 理解线程时间线图表的含义
    • 能够分析线程详细信息和栈跟踪
  3. 死锁检测与分析

    • 理解死锁的四个必要条件
    • 掌握使用 VisualVM 检测死锁的方法
    • 能够分析死锁循环链和解决方案
  4. 线程转储分析

    • 了解如何生成和分析线程转储文件
    • 掌握自动化分析工具的使用
    • 能够识别常见的线程问题模式

6.2 最佳实践

  1. 监控策略

    • 定期监控线程状态分布
    • 关注异常的线程状态模式
    • 建立线程监控告警机制
  2. 死锁预防

    • 实施锁排序策略
    • 使用超时锁机制
    • 避免嵌套锁的使用
  3. 性能优化

    • 识别线程瓶颈和热点
    • 优化锁竞争和等待时间
    • 合理配置线程池大小
  4. 故障诊断

    • 保存关键时刻的线程转储
    • 建立线程问题的诊断流程
    • 使用自动化工具进行分析

6.3 下一步学习

在下一章中,我们将学习:

  • 内存分析与堆转储:深入了解 Java 内存结构和垃圾回收
  • 堆转储生成与分析:掌握内存泄漏检测技巧
  • 对象引用分析:理解对象生命周期和内存占用
  • 内存优化策略:学习内存调优的最佳实践

通过本章的学习,你已经掌握了线程分析和死锁检测的核心技能,这为进一步的性能分析和优化奠定了坚实的基础。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐