大家好,今天小编关注到一个比较有意思的话题,就是关于java并发语言的,于是小编就整理了3个相关Java并发语言的解答,让我们一起看看吧。
在JAVA并发编程中,如何扩展和优化线程池?
在j***a中多线程并不陌生,在一定的范围内,多线程数量的增加会明显提升整个系统的吞吐性能,但是线程本身会极大的耗费内存空间,线程的频繁创建和回收也极其占用CPU***,多线程甚至会拖垮整个服务!
所以,线程的利用必须掌握在一个度,太少的线程数可能会浪费CPU***,而太高也极有可能反而降低整个应用性能;
线程池:基于使用多线程存在的问题,JDK提出了线程池技术,类似于数据库连接池,都是保持池中部分线程活跃状态,在需要使用线程的时候,直接从线程池中获取,使用。当线程使用结束,就进行回收(直接放回池中等待,而不是GC),这样就能避免了线程的频繁创建和回收。
J***A中的线程池:JDK提供了线程池框架Executor,帮助程序更好的管理线程。总的结构如下截图:
①newSingleThreadExecutor():返回单线程的线程池,一个接一个的处理任务,线程异常的时候,会创建新的线程替代; ②newFixedThreadPool:在达到最大线程之前,有一个任务就创建一个线程,直到达到最大线程数量; ③newCachedThreadPool:动态的设置最合适的线程数量,最大为JVM能够支持的大小; ④newScheduledThreadPool:指定线程数量,并周期性的执行任务; ⑤newSingleThreadScheduledExecutor:指定线程数量1个,并周期性的执行任务;
从源码来看,上面几种线程池底层都是封装的ThreadPoolExecutor对象,查看源码可知比较重要的属性(对象)截图如下:
定义了线程池中的线程数量,最大线程池数量,线程工厂(用于线程的创建),workQuere任务队列,handler拒绝策略等属性,用于线程池的对象初始化和任务调度!
下图是ThreadPoolExecutor对象中的execute方法截图:
解释如下:
线程池创建和销毁是有代价的,所以可以通过提前创建线程池来缓解这个问题。但是创建多少个是个问题?
一般根据业务复杂度,比如提前创建100个,然后设置一个低水位和高水位,比如20% 和80%,当达到低水位且持续一段时间,就可以释放一部分。当高水位一段时间后,可以动态增加一部分。同时增加手动设置的api可以根据预测提前调整。
J***a语言在哪些地方能够广泛的应用?
主要用于安卓app的开发,以及企业应用开发,也就是web开发的后端应用。还有少数地方用j***a的GUI库开发一些PC上的桌面应用,凭借j***a的跨平台特性,在mac,linux,windows上都能运行,只不过比较耗内存,eclipse,intellij等就是用j***a实现的桌面应用
J***a并发线程如何阻塞和唤醒?
J***a并发线程的阻塞和唤醒可分几类:
1. synchronize
基于JVM的对象头来实现,多线程争抢同一个临界***时根据不同的锁机制(自旋锁、轻/重量级锁)来进行阻塞和唤醒。
2. notify/wait,yeild等基础机制
这里暂时略过,大致实现原理是基于对象的同步队列和后面的AQS很像。
3. 并发组件的基础AQS
重点说下AQS(AbstractQueuedSynchronizer),
因为这是jdk并发包实现的基础(如Lock、BlockingQueue、CountdownLatch等)。
Aqs基本由一个volatile变量state和一个等待队列来实现,抢锁时先CAS修改state,失败以后就放到等待队列里,并通过LockSupport将线程挂起。
当锁的拥有者释放锁时会通过LockSupport唤醒等待队列的后续节点,让它再次去尝试抢锁(CAS修改state),如此反复。
掌握AQS的原理对理解jdk里很多并发组件非常有帮助。
1. sleep() 方法:以毫秒为单位,使线程处于阻塞状态,时间到了过后,自动唤醒。
2.suspend() 和 resume() 方法:挂起和唤醒线程,suspend e()使线程进入阻塞状态,只有对应的resume e()被调用的时候,线程才会进入可执行状态。这个不建议使用,容易发生死锁情况。
3. yield() 方法:调用 yield()的[_a***_]等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程
这里就说这三种吧,其它的你可以去csdn上门看看,学习一下
到此,以上就是小编对于j***a并发语言的问题就介绍到这了,希望介绍关于j***a并发语言的3点解答对大家有用。