Python 爬虫实战:使用 chardet 解决网页编码问题
2025/12/17 18:24:02
死锁是指两个或两个以上的线程在执行过程中,因抢夺资源而造成的一种互相等待的现象,若无外力干涉,则它们无法再继续推进下去
public class DeadLockDemo { static Object a = new Object(); static Object b = new Object(); public static void main(String[] args) { new Thread(() -> { synchronized (a){ System.out.println("t1线程持有a锁,试图获取b锁"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (b){ System.out.println("t1线程获取到b锁"); } } },"t1").start(); new Thread(() -> { synchronized (b){ System.out.println("t2线程持有a锁,试图获取a锁"); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (a){ System.out.println("t2线程获取到a锁"); } } },"t2").start(); } }分析:
a锁,再请求b锁b锁,再请求a锁public void transfer(Account from, Account to, int amount) { synchronized (from) { synchronized (to) { from.withdraw(amount); to.deposit(amount); } } }分析:
如果两个线程同时调用transfer(),但参数顺序相反:
transfer(account1, account2, 100)transfer(account2, account1, 200)可能产生死锁
ExecutorService executor = Executors.newFixedThreadPool(2); Future<?> future1 = executor.submit(() -> { Future<?> future2 = executor.submit(() -> System.out.println("Task2")); future2.get(); // 等待任务2完成 }); future1.get(); // 等待任务1完成分析:
始终按全局一致顺序获取锁
public void transfer(Account a, Account b, int amount) { Object firstLock = a.id < b.id ? a : b; Object secondLock = a.id < b.id ? b : a; synchronized (firstLock) { synchronized (secondLock) { // 操作 } } }用tryLock()替代synchronized,设置超时时间
if (lock1.tryLock(100, TimeUnit.MILLISECONDS)) { try { if (lock2.tryLock(100, TimeUnit.MILLISECONDS)) { try { // 操作 } finally { lock2.unlock(); } } } finally { lock1.unlock(); } }尽量只持有一个锁,或 将多个锁封装为一个大锁
jconsole —>win + R 输入 jconsole,连接对应的Java进程,点击线程,点击检测死锁即可查看