美文网首页
《Java核心技术 卷1》- 20240714

《Java核心技术 卷1》- 20240714

作者: 转岗做JAVA | 来源:发表于2024-07-13 18:45 被阅读0次
1.不要调用Thread类或者Runnable对象的run方法。
  • 直接调用run方法只会在同一个线程中执行任务,而没有启动新的线程;
  • 应当调用Thread.start方法,这会创建一个新线程来执行run方法;
2.现在线程优先级高度依赖系统。
  • Java有10个线程优先级(1~10),10最高,默认为5;
  • Windows有7个优先级别;面向Linux的Oracle JVM,会完全忽略线程优先级;
  • Java线程的优先级会映射到主机平台优先级;
  • 现在的Java线程优先级设定不是很有用,尽量不要使用了;
3. ReentrantLock(可重入)锁可以反复获取已拥有的锁。
  • 内部持有计数器来跟踪对lock方法的嵌套调用;每一层调用都需要unlock来释放;
4. 条件对象:Condition。
  • 一个锁对象可以有一个或者多个关联的条件对象。
  • 已获得锁的对象,当不满足条件对象的条件时,会暂停并释放锁;当条件满足后,又会从之前暂停的地方开始继续执行;
public void transfer(int from, int to, int amount) {
    bankLock.lock();
    try {
        while (accounts[from] < amount) { // 要用while,因为唤醒后还得再次检查条件
            // sufficientFunds = bankLock.newCondition();
            sufficientFunds.await();
            // transfer funds ...
            sufficientFunds.signalAll(); // 会激活等待这个条件的所有线程
        }
    }
}
  • 只有当线程拥有一个条件的锁时,才能在这个条件上调用await、signalAll或者signal方法;
5. synchronized 关键字(内部对象锁);
  • 每个Java对象都有一个内部锁;如果在一个方法上使用synchronized关键字,调用这个方法时,线程必须获得内部对象锁;
  • 每个内部对象锁只有一个关联条件;
  • 最好既不使用Lock/Condition,也不使用synchronized关键字,可以使用java.util.concurrent包的某些机制(比如阻塞队列)来更好的完成并发处理;
6. volatile字段

如果为了能并发读写一两个实例字段,可以不使用锁,而是使用volatile字段实现;

  • 标记为volatile的字段,编译器和虚拟机就会考虑到该字段可能被另一个线程更新;
  • 标记为volatile的字段,每次被某一线程修改时,最新值都会对所有线程可见;
  • volatile变量不能提供原子性;
// 无法保证读取、取反和写入操作不被中断;
public void flipDone() { done = !done; } // not atomic
7. stop和suspend方法已经废弃,不要使用;
  • stop方法可能会让对象被破坏,即未完成完整操作就被终止了;
  • suspend方法会挂起持有锁的线程,导致线程恢复前锁是不可用的;如果调用suspend方法的线程试图获取同一个锁,程序就会死锁;
8. 非线程安全的类可以通过ThreadLocal包装,来让各个线程独立访问;
public static final ThreadLocal<SimpleDateFormat> dateFormat = 
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
String dateStamp = dateFormat.get().format(new Date);

相关文章

网友评论

      本文标题:《Java核心技术 卷1》- 20240714

      本文链接:https://www.haomeiwen.com/subject/sbsqhjtx.html