今天闲来无事,总结一下多线程并发及线程锁的相关知识,我们日常的开发的流程一般是什么呢?一般就是顺序,选择,循环,对就这三个,一般我们就可以处理大部分的业务逻辑了,但是有些业务场景也不是很适用,那么我们今天就讲讲不适用的场景,今天要开运动会了,现在是400米决赛了,按照之前的处理方式,设计程序,你会发现问题好严重啊,程序是顺序执行,全跑完花了105秒,是不是问题太严重了呢,是的。那么如何解决了,其实我们考虑问题应该结合实际,不能上来就用程序实现,短跑都是同事气跑,齐头并进的跑,所以我们的解决方案是什么呢?并发,对就是并发,java为我们提供了非常好的线程解决方案。但是单单用线程性能不能保证,因为频繁的创建线程系统开销很高,所以我们使用线程池来根据实际业务事先建立一下线程,这样就可以快速的实现多线程处理。同时出发的问题说完了,大家是不是都已经明白了呢。接下来我们说说到终点的事情吧,到终点之后我们是不是要排个名,排出个1,2,3,4,5,6,7.。。。是的,说明什么问题呢,哈哈,就是要说明等大家都跑完才能出成绩是不是呢。是的,突然发现说话好贫,我想说的事如何分析业务场景,那么终点一般是会横一条线的,这是什么,代表终点,每个人都有一个终点。那么我们如何实现呢,为了避免计算机的循环等待,就是忙等(CPU资源使用率很高,不停判断),所以我们使用线程锁来实现我们的功能,每个人都有一个锁,当每个人都吧锁释放了的时候,程序就可以继续执行了。那么说回来了,什么时候需要这个线程锁呢,那就是多线程并发执行的时候,线程之间的执行进度是相互依赖的,就是必须同时完成时,我们就需要线程锁了。
需要说明一点,线程开多了对系统整体性能影响很大,我们在开发程序及程序设计之初,就应该对程序的配置CPU核心数,等关键参数进行设计定位,不然你用个单核CPU处理多线程,性能肯定不会很好,所以,适合的才是最好的,代码奉上,今天的总结是对自己学习的知识的一种记录,也是为了自己后续需要的参考。
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Action1 {
public static void main(String[] args) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
CountDownLatch countDownLatch=new CountDownLatch(3);
try {
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A出发30s");
countDownLatch.countDown();
}
});
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(40000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("B出发40s");
countDownLatch.countDown();
}
});
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(35000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("C出发35s");
countDownLatch.countDown();
}
});
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("The Match is over!");
cachedThreadPool.shutdown();
}
}输出结果如下:
A出发30s C出发35s B出发40s The Match is over!