Java线程从入门到实践

B站影视 电影资讯 2025-03-31 10:42 1

摘要:大家好,今天我们来聊聊Java线程这个让人又爱又恨的话题。作为一个Java开发者,谁没在深夜里对着死锁日志抓狂过?谁没被ConcurrentModificationException折磨得怀疑人生?今天我们就用轻松的方式,聊聊线程那些事儿。

java线程杂谈:从入门到“放弃”?

大家好,今天我们来聊聊Java线程这个让人又爱又恨的话题。作为一个Java开发者,谁没在深夜里对着死锁日志抓狂过?谁没被ConcurrentModificationException折磨得怀疑人生?今天我们就用轻松的方式,聊聊线程那些事儿。

一、线程的诞生:是继承Thread还是实现Runnable?

新手必问:"创建线程到底用继承Thread还是实现Runnable?"
答案很简单:优先选Runnable!为什么?

Java单继承的枷锁:继承Thread后你的类就不能继承其他爹了资源共享优势:多个线程可以共享同一个Runnable实例Lambda的魔法:new Thread( -> System.out.println("真香")).start;

但面试官总爱追问:"那Callable和Future呢?"
悄悄告诉你:当需要返回值或抛异常时,它们才是真香组合!

二、线程状态:比女朋友的心情还复杂

线程的6种状态(别数了,Java定义的就是6种):

NEW:刚new出来还没start的萌新RUNNABLE:在JVM眼里,就绪和运行都算runnableBlockED:拿着爱的号码牌等锁的苦主WAITING:望眼欲穿等唤醒的痴情种(wait/join)TIMED_WAITING:设了闹钟的等待(sleep(1000))TERMINATED:领盒饭退场

经典面试题:"sleep和wait的区别?"

sleep是Thread的静态方法,不释放锁wait是Object的方法,释放锁还要被notify

三、同步的艺术:synchronized的千层套路

java

// 对象锁的三种姿势

public synchronized void method {} // 等同于锁this

public void method { synchronized(this) {} }

public void method { synchronized(obj) {} }

// 类锁的正确打开方式

public static synchronized void staticMethod {} // 锁Class对象

但synchronized太重了怎么办?
试试ReentrantLock的三大绝招:

可中断等待:lock.lockInterruptibly公平锁:new ReentrantLock(true)条件变量:Condition condition = lock.newCondition

四、线程池:别重复造轮子!

为什么要用线程池?看看这血泪史:

频繁创建/销毁线程开销大不加管控的线程可能OOM缺乏统一管理(拒绝策略、监控等)

Executor框架的四大天王:

java

复制

Executors.newCachedThreadPool; // 线程数弹性伸缩

Executors.newFixedThreadPool(8); // 固定大小

Executors.newSingleThreadExecutor; // 单线程串行执行

Executors.newScheduledThreadPool(3); // 定时任务专家

但阿里规约为什么不让直接用Executors?
因为默认队列无界可能OOM!推荐手动newThreadPoolExecutor,七参数配置更灵活。

五、并发工具包:JUC大法好

CountDownLatch:老板等所有员工下班锁门

java

CountDownLatch latch = new CountDownLatch(3);

// 三个线程分别countDown

latch.await; // 阻塞直到计数器归零

CyclicBarrier:旅游团集合点等人齐发车

java

CyclicBarrier barrier = new CyclicBarrier(5, ->System.out.println("发车!"));

semaphore:海底捞等位区的叫号机

java

Semaphore semaphore = new Semaphore(5); // 5个许可

semaphore.acquire; // 获取许可

semaphore.release;

ConcurrentHashMap:线程安全的哈希表(比Hashtable高到不知哪里去了)

六、那些年我们踩过的坑

死锁现场

Ø 必要条件:互斥、占有且等待、不可抢占、循环等待

Ø 破局方法:jstack查线程栈,VisualVM在线监控

内存可见性

Ø volatile解决可见性问题(但不保证原子性)

Ø 经典案例:while(!stopFlag)可能永远不停止

ThreadLocal的魔幻现实

Ø 每个线程独立副本

Ø 但用完要remove!否则线程池复用会导致数据错乱

七、新世界大门:Java 8+的并发黑科技

CompletableFuture:异步编程利器

java

CompletableFuture.supplyAsync( -> "hello")

.thenApply(s -> s + " world")

.thenAccept(System.out::println);

并行流(Parallel Stream):一行代码实现并行处理

java

IntStream.range(1,100).parallel.sum;

StampedLock:读写锁的升级版,乐观读锁提升性能

结语:多线程修炼指南

精读《Java并发编程实战》(虽然可能看三遍才懂)多写demo,用jstack、VisualVM等工具分析参与开源项目,看别人怎么写并发代码牢记:没有银弹! 不同场景选择不同方案

互动话题:你遇到过最诡异的并发bug是什么?欢迎在评论区分享你的血泪史!

来源:老客数据一点号

相关推荐