欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

20200725——操作系统 线程间通信的方式

程序员文章站 2022-04-12 22:40:04
前言复习一下,进程间通信的方式有1)管道2)信号量3)消息队列4)共享内存5)socket远程调用volatile关键字/** * @Classname Test1 * @Description TODO * @Date 2020/7/25 23:26 * @Created by mmz */public class Test1 { static volatile boolean flag = true; public static void main(Stri...

前言

复习一下,进程间通信的方式有
1)管道
2)信号量
3)消息队列
4)共享内存
5)socket远程调用

volatile关键字

/**
 * @Classname Test1
 * @Description TODO
 * @Date 2020/7/25 23:26
 * @Created by mmz
 */
public class Test1 {
    static volatile boolean flag = true;

    public static void main(String[] args) {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int index = 10;
                while(true){
                    if(flag){
                        if(index !=0){
                            System.out.println("a");
                            flag = false;
                            index--;
                        }

                    }
                }
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    int index = 10;
                    if(!flag){
                        if(index != 0){
                            System.out.println("b");
                            flag = true;
                            index--;
                        }

                    }
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}

20200725——操作系统 线程间通信的方式
这种方式采用volatile关键字来实现线程间相互通信是使用共享内存的思想,多线程监听一个变量,当这个变量发生改变的时候,线程能够感知并执行相应的业务。

当然也可以打印多个字母,不限制的。三个线程打印abc

/**
 * @Classname Test2
 * @Description TODO
 * @Date 2020/7/25 23:35
 * @Created by mmz
 */
public class Test2 {
    static volatile int  number = 1;

    public static void main(String[] args) {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                int index = 10;
                while(true){
                    if(number == 1){
                        if(index != 0){
                            System.out.println("a");
                            number = 2;
                            index--;
                        }
                    }
                }
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                int index = 10;
                while(true){
                    if(number == 2){
                        if(index != 0){
                            System.out.println("b");
                            number = 3;
                            index--;
                        }
                    }
                }
            }
        });
        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                int index = 10;
                while(true){
                    if(number == 3){
                        if(index != 0){
                            System.out.println("c");
                            number = 1;
                            index--;
                        }
                    }
                }
            }
        });
        thread1.start();
        thread2.start();
        thread3.start();
    }

}

20200725——操作系统 线程间通信的方式

使用Object类的notify和wait

/**
 * @Classname Test3
 * @Description TODO
 * @Date 2020/7/25 23:40
 * @Created by mmz
 */
public class Test3 {
    static Object lock = new Object();
    static int number = 0;
    public static void main(String[] args) {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    int index = 10;
                    while(index != 0){
                        if(number == 0){
                            System.out.println("a");
                            number++;
                            index--;
                            try {
                                lock.notifyAll();
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                        try{
                            lock.wait();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }

            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    int index = 10;
                    while(index != 0){
                        if(number == 1){
                            System.out.println("b");
                            number++;
                            index--;
                            try {
                                lock.notifyAll();
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                        try{
                            lock.wait();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }

            }
        });
        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock){
                    int index = 10;
                    while(index != 0){
                        if(number == 2){
                            System.out.println("c");
                            number = 0;
                            index--;
                            try {
                                lock.notifyAll();
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                        try{
                            lock.wait();
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }

            }
        });

        thread1.start();
        thread2.start();
        thread3.start();
    }
}

20200725——操作系统 线程间通信的方式
声明一个Object类型的锁,sychronized直接上锁。进行业务逻辑判断。

工具类JUC下面的CountDownLatch

在aqs学习的时候,我们就提及到过CountDownLatch基于AQS框架。AQS并不陌生,一个state判断当前状态,一个共享线程判断当前是谁占有资源,一个CLH虚拟双向队列线程排位。

import com.sun.org.apache.bcel.internal.generic.NEW;

import java.util.concurrent.CountDownLatch;

/**
 * @Classname Test4
 * @Description TODO
 * @Date 2020/7/25 23:55
 * @Created by mmz
 */
public class Test4 {
    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        Thread threa1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("C等待其他人");
                try{
                    countDownLatch.await();
                }catch (Exception e){
                    e.printStackTrace();
                }
                System.out.println("C开始工作");

            }
        });
        Thread threa2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("A开始工作");
                countDownLatch.countDown();
            }
        });
        Thread threa3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("B开始工作");
                countDownLatch.countDown();
            }
        });
        threa1.start();
        threa2.start();
        threa3.start();

    }
}

但是这个代码好像就不能无限循环了,只能执行一次。其他线程都在执行countDown方法,让一开始定的计数器-1,只有await方法会在为0的时候调用,无法多线程一起被唤醒,相对于notifyAll和wait
20200725——操作系统 线程间通信的方式

还有ReentranLock中的condition

暂时不太了解,看了代码感觉有些复杂。不如wait和notifyAll

线程间同步的方式

互斥量 Synchronized/Lock:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问;当前拥有互斥对象的线程处理完任务后必须将互斥对象交出,以便其他线程访问该资源;
信号量 Semphare:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
事件(信号),Wait/Notify:允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。事件分为手动重置事件和自动重置事件。通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。

个人总结,关于进程与线程

进程是对运行时程序的封装,是系统对资源调度和分配的基本单位,实现了操作系统的并发。
线程是进程的子任务,一个进程至少有一个线程。线程基于进程存在。
进程在执行的过程中有独立的内存单元,多个线程共享进行的内存。

本文地址:https://blog.csdn.net/qq_36344771/article/details/107587119

相关标签: 操作系统