
嘻道奇闻
- 文章199742
- 阅读14625734
Java多线程开发必学:5大心方法提升并发效率
你写的Java程序是不是经常卡成PPT?明明电脑配置不差,处理批量数据却慢得像蜗牛?哎,这很可能是因为你的代码还在用单线程吭哧吭哧干活呢!今天咱们就来唠唠,怎么用5个核心方法让Java程序像开挂一样飞起来。
一、??线程池:拒绝996的重复造轮子??
你知道吗?每创建一个新线程就像雇个新员工,入职培训(分配内存)和离职手续(回收资源)都要花时间。假设要处理1000个任务,每次都招新人干活,光人事成本就能拖垮系统。这时候就该请出咱们的救星——??线程池??。
举个栗子,用Executors.newFixedThreadPool
开个5人小团队:
java复制ExecutorService pool = Executors.newFixedThreadPool(5); for(int i=0; i<1000; i++){ pool.execute(() -> { System.out.println(Thread.currentThread().getName()+"干活中"); }); } pool.shutdown();
这代码一跑起来你就会发现,虽然要干1000件活,但始终只有5个线程在轮班。既避免了反复招人,又防止系统被太多线程挤爆,这波血赚!
二、??Callable+Future:让线程会算数??
普通线程就像只会搬砖的力工,干完活连个验收单都不会写。想要线程把计算结果带回来?必须得用Callable
和Future
这对黄金搭档。
比如要算1到10000的和:
java复制Callable
task = () -> { int sum = 0; for(int i=1; i<=10000; i++) sum +=i; return sum; }; Future future = pool.submit(task); System.out.println("老板,算好了叫我啊~"); System.out.println("结果是:"+future.get()); //这里会等结果
这可比普通Runnable
强太多了,不仅能拿返回值,还能捕获异常。就像给工人配了部对讲机,随时掌握工地情况。
三、??锁的艺术:既要安全又要快??
多线程最头疼的就是数据错乱。比如两个线程同时给账户充值,不加锁的话分分钟余额对不上。但锁用不好又会导致性能暴跌,这事得讲究策略。
先看反面教材:
java复制// 全剧终写法 public synchronized void transfer(){ // 整个方法加锁 }
正确姿势应该是:
java复制public void transfer(){ // 无关代码... synchronized(lock){ // 只锁核心操作 } // 其他代码... }
用ReentrantLock
还能玩更骚的操作,比如尝试锁5秒,超时就放弃:
java复制if(lock.tryLock(5, TimeUnit.SECONDS)){ try { /*操作*/ } finally { lock.unlock(); } }
记住,锁的范围越小越好,就像疫情期间封控要精准到单元而不是整个小区。
四、??线程间聊天室:wait/notify的正确打开方式??
线程之间不能各干各的,得会配合。比如生产者造数据,消费者来取,这时候就要用wait()
和notify()
搞个消息群。
举个包子铺的例子:
java复制class 包子铺 { private int 包子数量=0; public synchronized void 做包子(){ while(包子数量>5){ wait(); //库存满了就歇会 } 包子数量++; notifyAll(); //喊吃货们来买 } public synchronized void 买包子(){ while(包子数量==0){ wait(); //没包子就等着 } 包子数量--; notifyAll(); //喊厨师开工 } }
注意这里要用while
而不是if
来检查条件,防止虚假唤醒。就跟等外卖要看APP状态,不能只听手机响一声就以为到了。
五、??性能调优三板斧??
-
??线程数别拍脑袋??:CPU密集型任务建议
核心数+1
,IO密集型可以设2*核心数
。不知道怎么算?用Runtime.getRuntime().availableProcessors()
查CPU核数啊! -
??并发工具真香??:别自己造轮子,
ConcurrentHashMap
比synchronizedMap
快不是一星半点。就像网购比线下扫货方便多了。 -
??原子操作治百病??:像计数器这种简单操作,用
AtomicInteger
比synchronized
快10倍不止。这玩意儿底层用的CPU指令,比Java锁高级多了。
??个人心得??:搞多线程就像带团队,既不能放任自流(不加锁),也不能管得太死(全局锁)。得把握个度,该放权时放权(无锁数据结构),该监管时监管(必要同步)。新手最容易犯的错就是过度设计,明明10个线程能搞定的事,非要搞100个,结果上下文切换把CPU都烧了。记住,多线程不是银弹,用得合适才是王道。