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

来源:互联网 发布:绝食减肥知乎 编辑:程序博客网 时间:2024/05/21 06:03

问题描述:现有一个主线程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 blocke.printStackTrace();}}System.out.println("子线程占用互斥信号量...");}public synchronized void releaseMutex(){//释放互斥信号量System.out.println("主线程执行完成,释放互斥信号量。。。");setSyn_flag(false);//唤醒等待System.out.println("通知子线程继续执行。。。");notify();}@Overridepublic void run() {// TODO Auto-generated method stubwhile(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 blocke.printStackTrace();}}//释放互斥信号量System.out.println("子线程释放互斥信号量。。。");setSyn_flag(false);try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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 blocke.printStackTrace();}}//释放互斥信号量System.out.println("子线程释放互斥信号量。。。");setSyn_flag(false);try {Thread.sleep(50);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.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 blocke.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 blocke.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 第一块0Online 第一块1main thread:1Online 第一块2main thread:2Online 第一块3main thread:3Online 第一块4cmd is comming...有互斥信号量,主线程等待...Online 第一块5Online 第一块6Online 第一块7Online 第一块8Online 第一块9子线程释放互斥信号量。。。主线程占用互斥信号量...pause the online thread...main thread:4Online thread wait...main thread:5main thread:6main thread:7主线程执行完成,释放互斥信号量。。。通知子线程继续执行。。。子线程占用互斥信号量...Online 第二块0start the online thread...main thread:8Online 第二块1main thread:9Online 第二块2main thread:10Online 第二块3cmd is comming...有互斥信号量,主线程等待...Online 第二块4Online 第二块5Online 第二块6Online 第二块7Online 第二块8Online 第二块9子线程释放互斥信号量。。。主线程占用互斥信号量...pause the online thread...main thread:11Online thread wait...main thread:12main thread:13main thread:14main thread:15main thread:16main thread:17主线程执行完成,释放互斥信号量。。。通知子线程继续执行。。。子线程占用互斥信号量...Online 第三块0start the online thread...main thread:18Online 第三块1main thread:19Online 第三块2main thread:20Online 第三块3main thread:21Online 第三块4main thread:22Online 第三块5Online 第三块6main thread:23


原创粉丝点击