java多线程互斥实战-模拟串口资源互斥



java多线程互斥实战-模拟串口资源互斥https://blog.csdn.net/qiandanfengyue/article/details/12882347

问题描述:现有一个主线程main,一个子线程online,online线程在启动后,如果没有互斥信号变量,会一直占用某个共享资源-比如串口。当主线程中有需要访问串口资源的时候,需要等待子线程执行完一个串口读写后释放互斥信号变量,才能占用串口资源,主线程执行完串口读写后,释放互斥信号变量,通知子线程继续执行。

举个例子:

子线程有三个块需要不停的访问串口资源,三个块的内部不能中断,需要等待一个块全部执行完,才能中断子线程。

如果这时假设子线程正好执行在第一块的中间,主线程有一个命令需要访问串口资源,那么这时主线程需要进入等待状态,等待子线程执行完一个块释放出互斥信号变量后,主线程才能执行,主线程执行串口访问资源时需要使子线程进入等待状态,当主线程执行完访问串口资源的操作后,释放出互斥信号变量,通知子线程进入执行状态。

子线程代码:

private static class Online implements Runnable{
private boolean syn_flag=false;//互斥信号量标志

public synchronized boolean isSyn_flag() {
return syn_flag;
}

public synchronized void setSyn_flag(boolean syn_flag) {
this.syn_flag = syn_flag;
}

private synchronized void waitForMutex(){
int i=0;
while(syn_flag){
try {
if(i<2){
System.out.println(“Online thread wait…”);
}
i++;
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(“子线程占用互斥信号量…”);
}

public synchronized void releaseMutex(){
//释放互斥信号量
System.out.println(“主线程执行完成,释放互斥信号量。。。”);
setSyn_flag(false);
//唤醒等待
System.out.println(“通知子线程继续执行。。。”);
notify();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
//是否需要等待
waitForMutex();
//占用互斥信号量
setSyn_flag(true);
for(int i=0;i<10;i++){
System.out.println(“Online 第一块”+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//释放互斥信号量
System.out.println(“子线程释放互斥信号量。。。”);
setSyn_flag(false);


try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//是否需要等待
waitForMutex();
//占用互斥信号量
setSyn_flag(true);
for(int i=0;i<10;i++){
System.out.println(“Online 第二块”+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//释放互斥信号量
System.out.println(“子线程释放互斥信号量。。。”);
setSyn_flag(false);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//是否需要等待
waitForMutex();
//占用互斥信号量
setSyn_flag(true);
for(int i=0;i<10;i++){
System.out.println(“Online 第三块”+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//释放互斥信号量
System.out.println(“子线程释放互斥信号量。。。”);
setSyn_flag(false);

}
}

}
主线程代码:

public static void main(String[] args) {
// TODO Auto-generated method stub
//启动子线程
Online online=new Online();
new Thread(online).start();

for(int i=0;i<100;i++){
System.out.println(“main thread:”+i);
try {
Thread.sleep(1200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(i==3||i==10){
//在i==3 i==10时模拟主线程需要操作串口资源。
//此时需要等待子线程执行完串口读写资源,当子线程读写完后会释放互斥信号变量,中断online线程
System.out.println(“cmd is comming…”);
viewMutex(online);
System.out.println(“pause the online thread…”);
}
if(i==7||i==17){
//在i==7 i==17时模拟主线程操作完串口资源。
//此时需要释放互斥信号变量,通知online线程继续执行
online.releaseMutex();
System.out.println(“start the online thread…”);
}
}

}
public static void viewMutex(Online online){
int i=0;
while(online.isSyn_flag()){//有互斥信号量,等待
if(i==0){
System.out.println(“有互斥信号量,主线程等待…”);
}
i++;
}
//无互斥信号量,占用
online.setSyn_flag(true);
System.out.println(“主线程占用互斥信号量…”);
}

打印结果如下:
main thread:0
子线程占用互斥信号量…
Online 第一块0
Online 第一块1
main thread:1
Online 第一块2
main thread:2
Online 第一块3
main thread:3
Online 第一块4
cmd is comming…
有互斥信号量,主线程等待…
Online 第一块5
Online 第一块6
Online 第一块7
Online 第一块8
Online 第一块9
子线程释放互斥信号量。。。
主线程占用互斥信号量…
pause the online thread…
main thread:4
Online thread wait…
main thread:5
main thread:6
main thread:7
主线程执行完成,释放互斥信号量。。。
通知子线程继续执行。。。
子线程占用互斥信号量…
Online 第二块0
start the online thread…
main thread:8
Online 第二块1
main thread:9
Online 第二块2
main thread:10
Online 第二块3
cmd is comming…
有互斥信号量,主线程等待…
Online 第二块4
Online 第二块5
Online 第二块6
Online 第二块7
Online 第二块8
Online 第二块9
子线程释放互斥信号量。。。
主线程占用互斥信号量…
pause the online thread…
main thread:11
Online thread wait…
main thread:12
main thread:13
main thread:14
main thread:15
main thread:16
main thread:17
主线程执行完成,释放互斥信号量。。。
通知子线程继续执行。。。
子线程占用互斥信号量…
Online 第三块0
start the online thread…
main thread:18
Online 第三块1
main thread:19
Online 第三块2
main thread:20
Online 第三块3
main thread:21
Online 第三块4
main thread:22
Online 第三块5
Online 第三块6
main thread:23

———————
作者:浅淡风月
来源:CSDN
原文:https://blog.csdn.net/qiandanfengyue/article/details/12882347
版权声明:本文为博主原创文章,转载请附上博文链接!