1、软件实现临界区域问题
在《操作系统概念(第七版)》中,7.2讨论了临界区域问题,下面给出算法和Java实现代码。
1.1 算法2
算法2的伪代码如下:
- do{
- flag[i]=true;
- while(flag[j]);
- 临界区;
- flag[i]=false;
- 剩余区;
- }while(1)
Java实现代码如下:
- package mutiple_thread;
- public class OS_SYN_A2{
- public static int flag[]=new int [3];
- public static int cnt=0;
- public static void main(String args[]){
- class proo implements Runnable{
- public proo(){
- }
- @Override
- public void run() {
- // TODO Auto-generated method stub
- while(true){
- flag[1]=1;
- while(flag[2]==1){
- }
- if(cnt==5){
- flag[1]=0;
- }else{
- cnt++;
- System.out.println("pro ++! now id"+cnt);
- flag[1]=0;
- }
- }
- }
- }
- class conn implements Runnable{
- @Override
- public void run() {
- // TODO Auto-generated method stub
- while(true){
- flag[2]=1;
- while(flag[1]==1){
- }
- //临界区
- if(cnt==0){
- flag[2]=0;
- }else{
- cnt--;
- System.out.println("con --! now id"+cnt);
- //退出临界区
- flag[2]=0;
- }
- }
- }
- }
- new Thread(new proo()).start();
- new Thread(new conn()).start();
- }
- }
这个算法的主要思路是通过设置flag来确定执行哪个线程,但是可能会造成饥饿,因此不行。
1.2 算法3
算法3通过共享两个变量 flag 和turn来实现同步。
- package mutiple_thread;
- public class OS_SYN_A3{
- public static int flag[]=new int [3];
- public static int turn=0;
- public static int cnt=0;
- public static void main(String args[]){
- class proo implements Runnable{
- public proo(){
- }
- @Override
- public void run() {
- // TODO Auto-generated method stub
- while(true){
- flag[1]=1;
- turn=2;
- while(flag[2]==1&&turn==2){
- }
- if(cnt==5){
- flag[1]=0;
- }else{
- cnt++;
- System.out.println("pro ++! now id"+cnt);
- flag[1]=0;
- }
- }
- }
- }
- class conn implements Runnable{
- @Override
- public void run() {
- // TODO Auto-generated method stub
- while(true){
- flag[2]=1;
- turn=1;
- while(flag[1]==1&&turn==1){
- }
- //临界区
- if(cnt==0){
- flag[2]=0;
- }else{
- cnt--;
- System.out.println("con --! now id"+cnt);
- //退出临界区
- flag[2]=0;
- }
- }
- }
- }
- new Thread(new proo()).start();
- new Thread(new conn()).start();
- }
- }
这是一种正确的软件实现方法。
2、经典同步问题的Java实现
2.1 读者写者问题
这里实现的读者优先的算法,使用了Java并发包的信号量来实现。
实现的伪代码如下:
读者进程:
- while(1){
- wait(mutex)
- count++;
- if(readercount==1){
- wait(writer);
- }
- signal(mutex);
- do reading;
- wait(mutex);
- cnt--;
- if(cnt==0){
- signal(writer);
- }
- signal(mutex);
- }
- }
算法通过共享writer和mutex两个信号量,来处理同步问题
- package mutiple_thread;
- import java.util.concurrent.Semaphore;
- public class OS_Readerwriter{
- static Semaphore sem=new Semaphore(1);
- static Semaphore sem_wrt=new Semaphore(1);
- static int readercount=0;
- static String a="hahaha";
- public static void main(String args[]){
- class reader implements Runnable{
- public reader(){
- }
- @Override
- public void run() {
- // TODO Auto-generated method stub
- try {
- sem.acquire();
- readercount++;
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- if(readercount==1){
- try {
- sem_wrt.acquire();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- sem.release();
- System.out.println("Reading "+a);
- try {
- sem.acquire();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- readercount--;
- if(readercount==0){
- sem_wrt.release();
- }
- sem.release();
- }
- }
- class writer implements Runnable{
- public writer(){
- }
- @Override
- public void run() {
- // TODO Auto-generated method stub
- try {
- sem_wrt.acquire();
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- a=a+"abc";
- System.out.println("Writing "+a);
- sem_wrt.release();
- }
- }
- for(int i=1;i<=10;i++){
- new Thread(new writer()).start();
- new Thread(new reader()).start();
- }
- }
- }