You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
以上几种线程池底层都是调用ThreadPoolExecutor来创建线程池的。 ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力。如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善。现代的PC都有多个CPU或一个CPU中有多个核,是否能合理运用多核的能力将成为一个大规模应用程序的关键。
线程基本使用
编写线程运行时执行的代码有两种方式:一种是创建Thread子类的一个实例并重写run方法,第二种是创建类的时候实现Runnable接口。当然,实现 Callable也算是一种方式,Callable和Future结合实现可以实现在执行完任务后获取返回值,而Runnable和Thread方式是无法获取任务执行后的结果的。
一旦线程启动后start()方法会立即返回,而不会等待run()方法执行完毕后返回,就好像run方法是在另外一个cpu上执行一样。
注意:创建并运行一个线程所犯的常见错误是调用线程的run()方法而非start()方法,如下所示:
起初你并不会感觉到有什么不妥,因为run()方法的确如你所愿的被调用了。但是,事实上,run()方法并非是由刚创建的新线程所执行的,而是当前线程所执行了。也就是被执行上面两行代码的线程所执行的。想要让创建的新线程执行run()方法,必须调用新线程的start方法。
Callable和Future结合实现实现在执行完任务后获取返回值:
volatile
在多线程并发编程中synchronized和Volatile都扮演着重要的角色,Volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的“可见性”。可见性的意思是当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。它在某些情况下比synchronized的开销更小,但是volatile不能保证变量的原子性。
volatile变量进行写操作时(汇编下有lock指令),该lock指令在多核系统下有2个作用:
多CPU下遵循缓存一致性原则,每个CPU通过嗅探在总线上传播的数据来检查自己的缓存值是否过期了,当发现缓存对应的内存地址被修改,将对应缓存行设置为无效状态,下次对数据操作会从系统内存重新读取。更多volatile知识请点击深入分析Volatile的实现原理。
synchronized
在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了。
Java中每一个对象都可以作为锁,当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常时必须释放锁。
synchronized关键字是不能继承的,也就是说基类中的synchronized方法在子类中默认并不是synchronized的。当线程试图访问同步代码块时,必须先获得锁,退出或抛出异常时释放锁。Java中每个对象都可以作为锁,那么锁存在哪里呢?锁存在Java对象头中,如果对象是数组类型,则虚拟机用3个word(字宽) 存储对象头,如果对象是非数组类型,则用2字宽存储对象头。更多synchronized知识请点击Java SE1.6中的Synchronized。
线程池
线程池负责管理工作线程,包含一个等待执行的任务队列。线程池的任务队列是一个Runnable集合,工作线程负责从任务队列中取出并执行Runnable对象。
Java通过Executors提供了4种线程池:
以上几种线程池底层都是调用ThreadPoolExecutor来创建线程池的。
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
阻塞队列有几种:
当提交新任务到线程池时,其处理流程如下:
Java并发知识点
sleep()和wait()的区别
sleep是任务进入休眠状态,这时该线程并不会释放锁(yield方法也是如此),而wait的时候线程被挂起,同时也释放锁,共享的资源可以被其他线程使用。
wait()和notify()是Object类方法,而sleep()和yield()是Thread类方法。wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。
The text was updated successfully, but these errors were encountered: