java 多线程饥饿现象的问题解决方法

java 多线程饥饿现象的问题解决方法

当有线程正在读的时候,不允许写 线程写,但是允许其他的读线程进行读。有写线程正在写的时候,其他的线程不应该读写。为了防止写线程出现饥饿现象,当线程正在读,如果写线程请求写,那么应该禁止再来的读线程进行读。

实现代码如下:

File.Java

package readerWriter; 

public class File {
private String name;
public File(String name)
{
  this.name=name; 

}
}

Pool.java

package readerWriter; 

public class Pool {
private int readerNumber=0;
private int writerNumber=0;
private boolean waittingWriten; 

public boolean isWaittingWriten() {
  return waittingWriten;
}
public void setWaittingWriten(boolean waittingWriten) {
  this.waittingWriten = waittingWriten;
} 

public File getFile() {
  return file;
}
public void setFile(File file) {
  this.file = file;
}
File file;
public Pool(File file)
{
  this.file=file; 

}
public int getReaderNumber() {
  return readerNumber;
}
public void setReaderNumber(int readerNumber) {
  this.readerNumber = readerNumber;
}
public int getWriterNumber() {
  return writerNumber;
}
public void setWriterNumber(int writerNumber) {
  this.writerNumber = writerNumber;
} 

}

Reader.java

package readerWriter; 

public class Reader implements Runnable{ 

  private String id;
  private Pool pool; 

  public Reader(String id,Pool pool)
  {
    this.id=id;
    this.pool=pool;
  } 

  @Override
  public void run()
  {
    // TODO Auto-generated method stub
    while(!Thread.currentThread().interrupted()){ 

    synchronized(pool){ 

        while(pool.getWriterNumber()>0 || pool.isWaittingWriten()==true)//当线程正在写或者
                                        //有线程正在等待写,则禁止读线程继续读
        { 

              try {
                pool.wait();
              } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
              } 

        } 

      { 

        pool.setReaderNumber(pool.getReaderNumber()+1);  

      }
    }
     System.out.println(id+" "+"is reading...."); 

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

    synchronized(pool)
    {
      pool.setReaderNumber(pool.getReaderNumber()-1);
      System.out.println(id+"  "+"is existing the reader....");
      if(pool.getReaderNumber()==0)
          pool.notifyAll();
    } try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    // pool.notifyAll(); 

  } 

  } 

}

Writer.java

package readerWriter; 

public class Writer implements Runnable{
  private Pool pool;
  String id;
  public Writer(String id,Pool pool)
  {
    this.id=id;
    this.pool=pool; 

  }
  @Override
  public void run() {
    // TODO Auto-generated method stub
    while(!Thread.currentThread().interrupted()){ 

    synchronized(pool){
      if(pool.getReaderNumber()>0)
        pool.setWaittingWriten(true);
      else
        pool.setWaittingWriten(false); 

      //当线程正在被读或者被写或者有线程等待读 

        while(pool.getWriterNumber()>0 ||  pool.getReaderNumber()>0)
        {
          try {
            pool.wait();
          } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
          } 

        }
      pool.setWaittingWriten(false);  //这个策略还算公平
      { 

        pool.setWriterNumber(pool.getWriterNumber()+1); 

      }
    }
     System.out.println(id+" "+"is writing...."); 

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

     //
    synchronized(pool)
    { 

      pool.setWriterNumber(pool.getWriterNumber()-1);
      System.out.println(id+"  "+"is existing the writer....");
      pool.notifyAll();
    }
     /* try {
        Thread.sleep(1000);
        //System.out.println("writer sleeping over");
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } */ 

  } 

}
}

Main.java

package readerWriter; 

public class Main { 

  public static void main(String[] args) {
    // TODO Auto-generated method stub
Pool pool=new Pool(new File("dd file"));
for(int i=0;i<2;i++)
{
 Thread writer=new Thread(new Writer("writer "+i,pool));
 writer.start();
}
for(int i=0;i<5;i++)
{ 

  Thread reader=new Thread(new Reader("reader "+i,pool));
  reader.start(); 

} 

  } 

}

程序部分运行结果如下:

writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
reader 0 is reading....
reader 0  is existing the reader....
writer 1 is writing....
writer 1  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
reader 3 is reading....
reader 2 is reading....
reader 4 is reading....
reader 1 is reading....
reader 0 is reading....
reader 3  is existing the reader....
reader 1  is existing the reader....
reader 0  is existing the reader....
reader 4  is existing the reader....
reader 2  is existing the reader....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 1 is writing....
writer 1  is existing the writer....
reader 2 is reading....
reader 2  is existing the reader....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....
writer 0  is existing the writer....
writer 0 is writing....

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • java多线程之火车售票系统模拟实例

    1.前言 为了学习多线程共享与通信,我们模拟一个火车售票系统,假设有10张火车票,三个窗口(也就是三个线程)同时进行售票. 2.非同步代码 package com.tl.skyLine.thread; /** * Created by tl on 17/3/6. */ public class SellTicket { public static void main(String[] args) { TicketWindow tw = new TicketWindow(); Thread t1

  • Java 多线程并发编程_动力节点Java学院整理

    一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进程的地址空间是互相隔离的:进程拥有各种资源和状态信息,包括打开的文件.子进程和信号处理. 线程:表示程序的执行流程,是CPU调度执行的基本单位:线程有自己的程序计数器.寄存器.堆栈和帧.同一进程中的线程共用相同的地址空间,同时共享进进程锁拥有的内存和其他资源. 2.Java标准库提供了进程和线程相关的API,进程主要包括表示进程的jav

  • Java Socket实现多线程通信功能示例

    本文实例讲述了Java Socket实现多线程通信功能的方法.分享给大家供大家参考,具体如下: 前面的文章<Java Socket实现单线程通信的方法示例>说到怎样写一个最简单的Java Socket通信,但是文章中的例子有一个问题就是Server只能接受一个Client请求,当第一个Client连接后就占据了这个位置,后续Client不能再继续连接,所以需要做些改动,当Server没接受到一个Client连接请求之后,都把处理流程放到一个独立的线程里去运行,然后等待下一个Client连接请求

  • 浅谈Java多线程实现及同步互斥通讯

    Java多线程深入理解本文主要从三个方面了解和掌握多线程: 1. 多线程的实现方式,通过继承Thread类和通过实现Runnable接口的方式以及异同点. 2. 多线程的同步与互斥中synchronized的使用方法. 3. 多线程的通讯中的notify(),notifyAll(),及wait(),的使用方法,以及简单的生成者和消费者的代码实现. 下面来具体的讲解Java中的多线程: 一:多线程的实现方式 通过继承Threa类来实现多线程主要分为以下三步: 第一步:继承 Thread,实现Thr

  • Java多线程的调度_动力节点Java学院整理

    有多个线程,如何控制它们执行的先后次序?         方法一:设置线程优先级. java.lang.Thread 提供了 setPriority(int newPriority) 方法来设置线程的优先级,但线程的优先级是无法保障线程的执行次序的,优先级只是提高了优先级高的线程获取 CPU 资源的概率.也就是说,这个方法不靠谱.       方法二:使用线程合并. 使用 java.lang.Thread 的 join() 方法.比如有线程 a,现在当前线程想等待 a 执行完之后再往下执行,那就

  • Java多线程并发编程(互斥锁Reentrant Lock)

    Java 中的锁通常分为两种: 通过关键字 synchronized 获取的锁,我们称为同步锁,上一篇有介绍到:Java 多线程并发编程 Synchronized 关键字. java.util.concurrent(JUC)包里的锁,如通过继承接口 Lock 而实现的 ReentrantLock(互斥锁),继承 ReadWriteLock 实现的 ReentrantReadWriteLock(读写锁). 本篇主要介绍 ReentrantLock(互斥锁). ReentrantLock(互斥锁)

  • java多线程学习之死锁的模拟和避免(实例讲解)

    1.死锁 死锁是这样一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放.由于线程被无限期地阻塞,因此程序不可能正常终止. Java 死锁产生的四个必要条件: 1.互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用 2.不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放. 3.请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有. 4.循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的

  • Java多线程 线程同步与死锁

     Java多线程 线程同步与死锁 1.线程同步 多线程引发的安全问题 一个非常经典的案例,银行取钱的问题.假如你有一张银行卡,里面有5000块钱,然后你去银行取款2000块钱.正在你取钱的时候,取款机正要从你的5000余额中减去2000的时候,你的老婆正巧也在用银行卡对应的存折取钱,由于取款机还没有把你的2000块钱扣除,银行查到存折里的余额还剩5000块钱,准备减去2000.这时,有趣的事情发生了,你和你的老婆从同一个账户共取走了4000元,但是账户最后还剩下3000元. 使用代码模拟下取款过

  • java 多线程饥饿现象的问题解决方法

    java 多线程饥饿现象的问题解决方法 当有线程正在读的时候,不允许写 线程写,但是允许其他的读线程进行读.有写线程正在写的时候,其他的线程不应该读写.为了防止写线程出现饥饿现象,当线程正在读,如果写线程请求写,那么应该禁止再来的读线程进行读. 实现代码如下: File.Java package readerWriter; public class File { private String name; public File(String name) { this.name=name; } }

  • Java多线程饥饿与公平介绍及代码示例

    如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为"饥饿".而该线程被"饥饿致死"正是因为它得不到CPU运行时间的机会.解决饥饿的方案被称之为"公平性" – 即所有线程均能公平地获得运行机会. 下面是本文讨论的主题: Java中导致饥饿的原因 在Java中,下面三个常见的原因会导致线程饥饿: 高优先级线程吞噬所有的低优先级线程的CPU时间. 线程被永久堵塞在一个等待进入同步块的状态,因为其他线程总是能在它之前持续

  • java 多线程的几种实现方法总结

    java 多线程的几种实现方法总结 1.多线程有几种实现方法?同步有几种实现方法? 多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 同步的实现方面有两种,分别是synchronized,wait与notify wait():使一个线程处于等待状态,并且释放所持有的对象的lock. sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常. notify():唤醒一个处于等待状态的线程,注意的是在调用此

  • java 多线程的同步几种方法

    java 多线程的同步几种方法 一.引言 前几天面试,被大师虐残了,好多基础知识必须得重新拿起来啊.闲话不多说,进入正题. 二.为什么要线程同步 因为当我们有多个线程要同时访问一个变量或对象时,如果这些线程中既有读又有写操作时,就会导致变量值或对象的状态出现混乱,从而导致程序异常.举个例子,如果一个银行账户同时被两个线程操作,一个取100块,一个存钱100块.假设账户原本有0块,如果取钱线程和存钱线程同时发生,会出现什么结果呢?取钱不成功,账户余额是100.取钱成功了,账户余额是0.那到底是哪个

  • Java多线程编程安全退出线程方法介绍

    线程停止 Thread提供了一个stop()方法,但是stop()方法是一个被废弃的方法.为什么stop()方法被废弃而不被使用呢?原因是stop()方法太过于暴力,会强行把执行一半的线程终止.这样会就不会保证线程的资源正确释放,通常是没有给与线程完成资源释放工作的机会,因此会导致程序工作在不确定的状态下 那我们该使用什么来停止线程呢 Thread.interrupt(),我们可以用他来停止线程,他是安全的,可是使用他的时候并不会真的停止了线程,只是会给线程打上了一个记号,至于这个记号有什么用呢

  • java 多线程的三种构建方法

    java  多线程的三种构建方法 继承Thread类创建线程类 public class Thread extends Object implements Runnable 定义Thread类的子类,并重写其run()方法 创建Thread子类的实例,即创建了线程对象 调用线程对象的start()方法启动线程 public class FirstThread extends Thread { public void run(){ for(int i=0;i<100;i++){ /* * Thre

  • java多线程之停止线程的方法实例代码详解

    和线程停止相关的三个方法 /* 中断线程.如果线程被wait(),join(),sleep()等方法阻塞,调用interrupt()会清除线程中断状态,并收到InterruptedException异常.另外interrupt();对于isAlive()返回false的线程不起作用. */ public void interrupt(); /* 静态方法,判断线程中断状态,并且会清除线程的中断状态.所以连续多次调用该方法,第二次之后必定返回false.另外,isAlive()用于判断线程是否处于

  • Java 多线程传值的四种方法

    其实大家都知道多线程传值有三种方式: 1:通过构造方法传递数据 2:通过变量和方法传递数据 3:通过回调函数传递数据 那么博主有个非常变态的需求,所以找出了第四种实现方式,先看效果图: 动态Cron4j调度器,我曾经发过类似的文章,可以去搜索一下. 点击执行走下边的代码,然后根据类名反编译 public static void executeCron4j(String packageClass){ try { Object taskObj = classNewInstance(packageCl

  • java多线程累加计数的实现方法

    题目 给定count=0:让5个线程并发累加到1000: 思路 创建一个类MyRunnable,实现Runnable(继承Thread类也可) 定义一个公共变量count(初始值为0),5个线程都可以访问到: 创建5个线程并发递增count到1000: 注意 这块注意Thread和Runnable类的区别,Thread类是线程类,可以直接new Thread().start运行.而Runnable类是任务类,需要一个线程来承载任务,通过new Thread(new Runnable()).sta

  • java  多线程的三种构建方法

    java  多线程的三种构建方法 继承Thread类创建线程类 public class Thread extends Object implements Runnable 定义Thread类的子类,并重写其run()方法 创建Thread子类的实例,即创建了线程对象 调用线程对象的start()方法启动线程 public class FirstThread extends Thread { public void run(){ for(int i=0;i<100;i++){ /* * Thre

随机推荐