【JUC】一篇通关JUC并发之共享模型

目录

  • 1. 共享带来的问题
    • 1-1. 临界区 Critical Section
    • 1-2. 竞态条件 Race Condition
    • 1-3. synchronized 解决方案
      • 3-1. 方法上的 synchronized

1. 共享带来的问题

1-1. 临界区 Critical Section

  • 一个程序运行多个线程本身是没有问题的
  • 问题出在多个线程访问共享资源
    • 多个线程读共享资源其实也没有问题
    • 在多个线程对共享资源读写操作时发生指令交错,就会出现问题
  • 一段代码块内如果存在对共享资源多线程读写操作,称这段代码块为临界区

例如

	static int counter = 0;
	static void increment() 
	// 临界区
	{ 
	 counter++;
	}
	static void decrement() 
	// 临界区
	{ 
	 counter--;
	}

1-2. 竞态条件 Race Condition

  • 多个线程在临界区内执行,由于代码的执行序列不同而导致结果无法预测,称之为发生了竞态条件

1-3. synchronized 解决方案

为了避免临界区的竞态条件发生,有多种手段可以达到目的。

  • 阻塞式的解决方案:synchronized,Lock
  • 非阻塞式的解决方案:原子变量

synchronized,即俗称的【对象锁】,它采用互斥的方式让同一时刻至多只有一个线程能持有【对象锁】,其它线程再想获取这个【对象锁】时就会阻塞住。这样就能保证拥有锁的线程可以安全的执行临界区内的代码,不用担心线程上下文切换

注意
虽然 java 中互斥和同步都可以采用 synchronized 关键字来完成,但它们还是有区别的:

  • 互斥是保证临界区的竞态条件发生,同一时刻只能有一个线程执行临界区代码
  • 同步是由于线程执行的先后、顺序不同、需要一个线程等待其它线程运行到某个点

语法

synchronized(对象) // 线程1, 线程2(blocked)
{
 临界区
}

案例

【JUC】一篇通关JUC并发之共享模型_第1张图片
【JUC】一篇通关JUC并发之共享模型_第2张图片
思考

synchronized实际是用对象锁保证了临界区内代码的原子性,临界区内的代码对外是不可分割的,不会被线程切换所打断。

3-1. 方法上的 synchronized

synchronized只能锁对象

【JUC】一篇通关JUC并发之共享模型_第3张图片
【JUC】一篇通关JUC并发之共享模型_第4张图片

你可能感兴趣的:(JUC并发编程,java,java-ee)