详解线程同步和线程互斥,Java如何实现线程同步和互斥

Posted BarryYan_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解线程同步和线程互斥,Java如何实现线程同步和互斥相关的知识,希望对你有一定的参考价值。

1 Why?

首先第一个问题,为什么进行线程同步和线程互斥?

最开始我们的操作系统的作业的调度单位是进程,但是由于每个进程都单独占据一个资源,而且进程的形态转换非常的耗费系统资源。

为了系统的调度更加轻量级,能够更好的支持并发,因此引入了线程这个概念。

PS:进程和线程的关系:

  • 线程是进程的一个实体
  • 同一进程内的不同线程共享该进程的系统资源
    详解线程同步和线程互斥,Java如何实现线程同步和互斥_开发语言
    所以问题的答案来了,因为同一进程内的不同线程共享该进程的系统资源,这就导致了资源竞争的问题,​​​为了能够解决这个问题,所以引入了线程互斥,就是为了能够在单位时间内只有一个线程共享该进程的系统资源​​​。而​​进程同步就是让多个线程合理有序的访问该进程的系统资源。​

2 What?

什么是线程同步?什么是线程互斥?

线程同步和线程互斥,类似于进程同步和进程互斥,在《操作系统》这本书中有另一个好听的名字:直接制约和间接制约

直接制约(同步关系):

某些应用程序,为了完成某个任务而建立了两个或多个进程(源于进程间的合作)。
详解线程同步和线程互斥,Java如何实现线程同步和互斥_线程同步_02
间接制约(互斥关系):

多个程序并发执行时,由于共享系统资源(如CUP、I/O设备等)而导致这些并发执行的程序之间形成相互的制约

的关系。
详解线程同步和线程互斥,Java如何实现线程同步和互斥_线程同步_03
因此,我们知道了线程同步和线程互斥的关系:

  1. 互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性,访问是无序的。
  2. 同步是指在互斥的基础上,通过其它机制实现访问者对资源的有序访问。
  3. 同步其实已经实现了互斥,所以同步是一种更为复杂的互斥。
  4. 互斥是一种特殊的同步。

3 How?

Java如何实现线程同步和线程互斥?

先说简单的,Java实现线程互斥:

无线程互斥的情况

/**
* @desc: 没有进行互斥的情况
* @author: YanMingXin
* @create: 2021/12/19-18:02
**/
public class Method0

private int value = 10;

private void reduce()
try
while (value == 0)
System.out.println("stop...");
return;

System.out.println(Thread.currentThread().getName() + ":" + value);
value--;
catch (Exception e)
e.printStackTrace();



private void make()
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 5, 3, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
for (int i = 0; i < 20; i++)
poolExecutor.execute(() ->
reduce();
);



public static void main(String[] args)
Method0 methodA = new Method0();
methodA.make();


方式一:互斥锁synchronized

/**
* @desc: 互斥方式一
* @author: YanMingXin
* @create: 2021/12/19-17:48
**/
public class MethodA

private int value = 10;

private synchronized void reduce()
try
while (value == 0)
System.out.println("stop...");
return;

System.out.println(Thread.currentThread().getName() + ":" + value);
value--;
catch (Exception e)
e.printStackTrace();



private void make()
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 5, 3, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
for (int i = 0; i < 20; i++)
poolExecutor.execute(() ->
reduce();
);



public static void main(String[] args)
MethodA methodA = new MethodA();
methodA.make();


方式二:可重入互斥锁ReentrantLock

/**
* @desc: 互斥方式二
* @author: YanMingXin
* @create: 2021/12/19-17:50
**/
public class MethodB

private int value = 10;

private ReentrantLock lock=new ReentrantLock();


private void reduce()
lock.lock();
try
while (value == 0)
System.out.println("stop...");
return;

System.out.println(Thread.currentThread().getName() + ":" + value);
value--;
catch (Exception e)
e.printStackTrace();
finally
lock.unlock();



private void make()
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(3, 5, 3, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
for (int i = 0; i < 20; i++)
poolExecutor.execute(() ->
reduce();
);



public static void main(String[] args)
MethodB methodA = new MethodB();
methodA.make();


然后,Java实现线程同步:

无线程同步的情况

/**
* @desc: 无线程同步状态
* @author: YanMingXin
* @create: 2021/12/19-17:47
**/
public class Method0

private int value = 0;

private static List list = new ArrayList<String>();

static
list = Arrays.asList("1-Insert", "2-Delete", "3-Update", "4-Select");


private void reduce()
try
System.out.println(list.get(value));
JAVA多线程提高二:传统线程的互斥与同步&传统线程通信机制

Linux 线程同步都有哪些方法?

并发与多线程——同步与互斥

内核线程与用户线程区别同步互斥的实现原理——详解

如何创建线程?如何保证线程安全?

Linux多线程中互斥锁读写锁自旋锁条件变量信号量详解