对于非线程所有者的代码来说,应该小心地保存中断状态,这样拥有线程的代码才能对中断做出响应。批评者嘲笑 java 的中断功能,因为它没有提供抢占式的中断机制,而且还强迫开发人员必须处理 InterruptedException。然而,通过推迟中断请求的处理,开发人员能定制更灵活的中断策略,从而使程序在响应性和健壮性之间实现合理的平衡。
AI时代,有人焦虑失业,有人偷偷变强,不写代码不烧脑~
相关语录
-
当每个操作都请求多个变量时,锁的粒度将很难降低。这是在性能与可伸缩性之间相互制衡的另一个方面,一些常见的优化措施,例如将一些反复计算的结果缓存起来,都会引入一些“热点域”,而这些热点域往往会限制可伸缩性。
-
通过并发容器来替代同步容器,可以极大地提高伸缩性并降低风险。
-
因此,CompletionService的作用就相当于一组计算的句柄,这与Future作为单个计算的句柄是非常相似的。
-
无论其她的线程会对已发布的引用执行何种操作,其实都不重要,因为误用该引用的风险始终存在。如果有人窃取了你的密码并发布到alt.passwords新闻组上,那么你的信息将“逸出”:无论是否有人会恶意地使用这些个人信息,你的账户都已经不再安全了。发布一个引用同样会带来类似的风险。
-
加锁机制既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性。当且仅当满足以下所有条件时,才应该使用volatile变量:-对变量的写入操作不依赖变量的当前值,或者你能确保只有单个线程更新变量的值。-该变量不会与其它状态变量一起纳入到不变性条件中。-在访问变量时不需要加锁。
-
如果线程池较小而队列较大,那么有助于减少内存使用量,降低CPU的使用率,同时还可以减少上下文切换,但付出的代价是可能会限制吞吐量。只有当任务相互独立时,为线程池或工作队列设置界限才是合理的。如果任务之间存在依赖性,那么有界的线程池或队列就可能导致线程“饥饿”死锁问题。此时应该使用无界的线程池。
-
如果在调用某个方法时不需要持有锁,那么这种调用称为开放调用。依赖于开放调用的类通常能表现出更好的行为,并且与那些正在调用方法时需要持有锁的类相比,也更容易编写。分析一个完全依赖于开放调用的程序的活跃性,要比分析那些不依赖开放调用的程序的活跃性简单。在重新编写同步代码块以使用开放调用时会产生意想不到的结果,因为这会使得某个原子操作变为非原子操作。在许多情况下,使某个操作失去原子性是可以接收的。
-
在LeftRightDeadLock或transferMoney中,要查找死锁是比较简单的,只需要找出那些需要获得两个锁的方法。然而要在Taxi和Dispatcher中查找死锁则比较困难:如果在持有锁的情况下调用某个外部方法,那么就需要警惕死锁。
-
当满足以下条件时,对象才是不可变的:-对象创建以后其状态就不可修改-对象的所有域都是final类型-对象时正确创建的(在对象的构造期间,this引用没有逸出)从技术上来看,不可变对象并不需要将其所有的域都声明为final类型,例如String就是这种情况,这就要对类的良性数据竞争情况做精确的分析,因此需要深入理解Java的内存模型。...自己在编码时不要这么做。
-
在java类库中,任务执行的主要抽象对象不是Thread,而是Executor
-
线程封闭技术的另一种常见应用是JDBC的Connection对象。JDBC规范并不要求Connection对象必须是线程安全的。在典型的服务器应用程序中,线程从连接池中获得一个Connection对象,并且用该对象来处理请求,使用完后再将对象返还给连接池。...这种连接管理模式在处理请求时隐含地将Connection对象封闭在线程中。
-
双赢者把生活看作一个合作的舞台,而不是一个角斗场。一般人看事情多用二分法:非强即弱,非胜即败。其实世界之大,人人都有足够的立足空间,他人之得不必就视为自己之失。人际交往的六种模式双赢不是什么技巧,而是人际交往的哲学,是六个交往模式之一,这六个模式分别是:◎利人利己(双赢)◎损人利己(赢/输)◎舍己为人(输/赢)◎两败俱伤(输/输)◎独善其身(赢)◎好聚好散(无交易)“我认输,你赢了。”“就这样吧,

