第12章 并发

第12章 并发

  • 进程:每个进程拥有自己的一套完整变量;
  • 线程:多个线程共享数据,通信更有效、更容易,开销小。

12.1 什么是线程

// Runnable接口,只有一个方法run(),函数式接口
Runnable r = () -> { task code }; // 用lambda创建一个实例
var t = new Thread(r);
t.start();
// 不要用Thread或Runnable对象的run方法,只是在同一个进程中执行;用Thread.start。创建新进程

12.2 线程状态

  • new:新建 var t = new Thread(r); // 还未运行
  • Runnable:可运行 t.start(); // 可能正在运行也可能没运行,操作系统提供运行时间
    Thread.yield(); // 当前正在执行的线程交出运行权 静态方法
  • Blocked:阻塞 // 试图获取内部对象锁
  • Waiting:等待 Thread.join(); // 线程等待另一个线程通知调度器出现一个条件时
  • Timed waiting:计时等待 Thread.sleep(); // 调用带超时参数的方法
  • Terminated:终止 // run正常退出;产生没有捕获到的异常

在这里插入图片描述

12.3 线程属性

中断线程: t.interrupt(); Thread.currentThread().isInterrupted();
如果线程被阻塞 sleep(); wait(); ,无法检查中断状态,引入InterruptedException异常 catch (InterruptedException e){}

守护线程: t.setDaemon(true); // 为其他线程提供服务,如计时器

线程名:t.setName("name");

12.4 同步

竞态条件:两个及以上的线程共享同一数据的存取,若同时修改,两个线程会相互覆盖。

锁对象:ReentrantLock类

// 重入锁(需保证访问同一个锁对象)
var myLock = new ReentrantLock();
myLock.lock();
try 
{
	...
}
finally
{
	myLock.unlock();
}

条件对象:管理获得了锁却不能工作的线程

Condition name = myLock.newCondition();
name.await(); // 阻塞, 放弃已获得的锁, 进入等待集
name.signalAll(); // 解除所有等待线程的阻塞

synchronized关键字(同步方法):一个方法声明后,对象的锁将保护整个方法(线程调用其必须获得内部对象锁,每个Java对象都有一个锁)

public synchronized void method()
{
	...
	wait(); // 将线程添加到等待集
	notifyAll(); // 解除等待线程的阻塞
	// 等价于上述的条件对象
}

同步块:获得Java对象的锁

synchronized(obj)
{
	... // 
}

监视器

  • 只包含私有字段的类;
  • 监视器类的每个对象都有一个关联的锁;
  • 所有方法由这个锁锁定;
  • 锁可以有任意多个相关联的条件。

Java对象

  • 字段不要求是private;
  • 方法不要求是synchronized;
  • 内部锁对客户是可用的。

volatile:为实例字段的同步访问提供了一种免锁机制,编译器和虚拟机知道该字段可能被另一个线程并发更新。public volatile boolean done; // 不提供原子性

原子性:java.util.concurrent.atomic 提供机器级指令保证其他操作的原子性

死锁

线程局部变量

// 为每个线程构造一个实例
public static final ThreadLocal<SimpleDateFormat> dateFormat = 
				ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
String dateStamp = dateFormat.get().format(new Date());

废弃方法

  • stop :终止所有未结束方法,造成对象处于不一致状态;
  • suspend:会挂起一个持有锁的线程,在其恢复前该锁不可用。

12.5 线程安全的集合

阻塞队列:LinkedBlockingQueue LinkedBlockingDeque ArrayBlockingQueue PriorityBlockingQueue DelayQueue

// 有必要时全会阻塞
put // 如果队列满,则阻塞
take // 如果队列空,则阻塞
add // 如果队列满,抛出IllegalStateException异常
remove // 如果队列空,抛出NoSuchElementException异常
element // 如果队列空,抛出NoSuchElementException异常
offer // 如果队列满,则返回false
peek poll // 如果队列空,则返回null (因此,这些队列不能插入null)

映射条目的原子更新

import java.util.concurrent;
ConcurrentHashMap  // 不允许有null
map.merge(key, 1L, Long::sum);
ConcurrentSkipListMap
ConcurrentSkipListSet
ConcurrentLinkedQueue

并发集视图:Set<String> words = ConcurrentHashMap.<String>newKeySet();

12.6 任务和线程池

12.7 异步计算

12.8 进程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值