当前位置: 移动技术网 > 科技>办公>内存 > 20200725——操作系统 线程间通信的方式

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

2020年07月27日  | 移动技术网科技  | 我要评论

前言

复习一下,进程间通信的方式有
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();
    }
}

在这里插入图片描述
这种方式采用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();
    }

}

在这里插入图片描述

使用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();
    }
}

在这里插入图片描述
声明一个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
在这里插入图片描述

还有ReentranLock中的condition

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

线程间同步的方式

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

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

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

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

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网