有几种思路
1、利用信号量来实现读者写者的互斥(读者和读者之间是并行的)
public class ReaderAndWriter
{
private static AtomicInteger reader = new AtomicInteger();
private static AtomicInteger blocked = new AtomicInteger();
//用来对读者写者互斥
private static Semaphore ws = new Semaphore(1,true);
public static void main(String[] args)
{
System.out.println("Hello World!");
ExecutorService executors = Executors.newFixedThreadPool(5);
executors.execute(new Writerr());
executors.execute(new Readerr(1));
executors.execute(new Readerr(2));
executors.execute(new Readerr(3));
executors.execute(new Readerr(4));
executors.shutdown();
}
static class Writerr implements Runnable
{
public void run(){
try{
while(true){
ws.acquire();
write();
//System.out.println("正在等待:" + ws.getQueueLength()+"-------"+blocked.get());
ws.release(blocked.get()==0 ? 1: blocked.get());
blocked.set(0);
}
}catch(InterruptedException ex){
}
}
private static void write(){
try{
System.out.println("writing...");
Thread.sleep((new Random().nextInt(2))*1000);
System.out.println("writed!");
}catch(InterruptedException ex){
}
}
}
static class Readerr implements Runnable
{
private int id;
public Readerr(int id){
this.id = id;
}
public void run(){
try{
while(true){
if(reader.get() == 0){
blocked.getAndIncrement();
ws.acquire();
}
//以原子方式将当前值加 1
reader.getAndIncrement();
read();
//以原子方式将当前值减 1
reader.getAndDecrement();
if(reader.get() == 0){
ws.release();
}
//出让时间,不与writer过度竞争
//System.out.println("["+id+"]出让时间");
Thread.sleep(6000);
}
}catch(InterruptedException ex){
}
}
private void read(){
try{
System.out.println("["+id + "]reading...");
Thread.sleep((new Random().nextInt(10))*1000);
System.out.println("["+id+"]read!");
}catch(InterruptedException ex){
}
}
}
}
2、利用synchronized对实现读者写者互斥
public class ReaderAndWriter1
{
public static FILE file = new FILE();
public static void main(String[] args)
{
System.out.println("Hello World!");
ExecutorService executors = Executors.newFixedThreadPool(5);
executors.execute(new Writerr());
executors.execute(new Readerr(1));
executors.execute(new Readerr(2));
executors.execute(new Readerr(3));
executors.execute(new Readerr(4));
executors.shutdown();
}
static class Writerr implements Runnable
{
public void run(){
while(true){
file.write();
}
}
}
static class Readerr implements Runnable
{
private int id;
public Readerr(int id){
this.id = id;
}
public void run(){
try{
while(true){
file.read(id);
//出让时间,不与writer过度竞争
//System.out.println("["+id+"]出让时间");
Thread.sleep(6000);
}
}catch(InterruptedException ex){
}
}
}
}
class FILE
{
//读者数
private static AtomicInteger reader = new AtomicInteger(0);
//写者数
private static AtomicInteger writer = new AtomicInteger(0);
//写文件
public void write(){
try{
synchronized(reader){
if(reader.get() > 0)
{
reader.wait();
}
}
synchronized(writer){
writer.getAndIncrement();
System.out.println("writing...");
Thread.sleep((new Random().nextInt(2))*1000);
System.out.println("writed!");
writer.getAndDecrement();
writer.notifyAll();
}
}catch(InterruptedException ex){
}
}
//读文件
public void read(int id){
try{
synchronized(writer){
if(writer.get() > 0){
writer.wait();
}
}
reader.getAndIncrement();
System.out.println("["+id + "]reading...");
Thread.sleep((new Random().nextInt(10))*1000);
System.out.println("["+id+"]read!");
reader.getAndDecrement();
synchronized(reader){
if(reader.get() == 0){
reader.notify();
}
}
}catch(InterruptedException ex){
}
}
}
3、concurrent包中提供了读者写者锁
ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。
Lock readLock() 返回用于读取操作的锁。
Lock writeLock() 返回用于写入操作的锁
//很简洁的程序
public class ReaderAndWriter2
{
public static FILE file = new FILE();
public static void main(String[] args)
{
System.out.println("Hello World!");
ExecutorService executors = Executors.newFixedThreadPool(5);
executors.execute(new Writerr());
executors.execute(new Readerr(1));
executors.execute(new Readerr(2));
executors.execute(new Readerr(3));
executors.execute(new Readerr(4));
executors.shutdown();
}
static class Writerr implements Runnable
{
public void run(){
while(true){
file.write();
}
}
}
static class Readerr implements Runnable
{
private int id;
public Readerr(int id){
this.id = id;
}
public void run(){
try{
while(true){
file.read(id);
//出让时间,不与writer过度竞争
//System.out.println("["+id+"]出让时间");
Thread.sleep(6000);
}
}catch(InterruptedException ex){
}
}
}
}
//文件类
class FILE
{
//利用concurrent工具包中的读写锁
private static ReadWriteLock lock = new ReentrantReadWriteLock();
//写锁
private static Lock write = lock.writeLock();
//读锁
private static Lock read = lock.readLock();
//写操作
public static void write(){
try{
write.lock();
System.out.println("writing....");
Thread.sleep(new Random().nextInt(3)*1000);
System.out.println("writed!");
}catch(InterruptedException ex){
}finally{
write.unlock();
}
}
//读操作
public static void read(int id){
try{
read.lock();
System.out.println("["+id+"]reading....");
Thread.sleep(new Random().nextInt(5)*1000);
System.out.println("["+id+"]read!");
//出让时间
Thread.sleep(6000);
}catch(InterruptedException ex){
}finally{
read.unlock();
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-12 22:48:23