启动4个线程,向4个文件A,B,C,D里写入数据,每个线程只能写一个值。
线程1:只写1
线程2:只写2
线程3:只写3
线程4:只写4
4个文件A,B,C,D。
程序运行起来,4个文件的写入结果如下:
A:12341234...
B:23412341...
C:34123412...
D:41234123...
下面是我的解题的java代码,编译环境为jdk1.8,读者们在编译器中,创建一个包叫TestThread,并复制以下代码,就不用手动导包了。
代码:
package TestThread;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Google {
public static void main(String[] args) throws InterruptedException {
//File是自己定义的类,用来模拟文件
//文件A接下来需要的字母
File fileA = new File(1, "fileA");
//文件A接下来需要的字母
File fileB = new File(2, "fileB");
//文件A接下来需要的字母
File fileC = new File(3, "fileC");
//文件A接下来需要的字母
File fileD = new File(4, "fileD");
//文件数组
File[] files = {fileA,fileB,fileC,fileD};
//读写锁
ReadWriteLock lock = new ReentrantReadWriteLock();
//产品队列
BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
//线程池
ExecutorService threadPool = Executors.newFixedThreadPool(8);
//启动四个线程写入数据
for(int i = 1 ; i <= 4 ; i ++){
final int content = i;
threadPool.execute(()->{
try {
while(true){
//向队列放数据
Thread.sleep(1000);
queue.put(content);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
});
}
//启动四个线程读数据
for(File file : files){
//文件A
threadPool.execute(()->{
while(true){
//死循环 读取所需要的内容
try {
//线程睡眠,方便观察输出内容
Thread.sleep(1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//上读锁
lock.readLock().lock();
try {
//判断队列中是否有 文件 需要内容
while(file.myNeed( queue.peek() )){
//上写锁
lock.readLock().unlock();
lock.writeLock().lock();
try {
//再次查看数据,因为有可能挂写锁之前被别人挂了写锁
//导致数据发生改变,并不是这个文件需要的数据
Integer content = queue.peek();
if(file.myNeed(content)){
//确认无误,添加内容到文件
file.addContent(content);
//从队列中删除数据
queue.take();
//展示一下文件内容
file.show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//上读锁,配合外层的finaly 否则会抛出异常
lock.readLock().lock();
//释放写锁
lock.writeLock().unlock();
}
}
} finally {
lock.readLock().unlock();
}
}
});
}
}
}
class File{
public File(Integer need, String fileName) {
super();
this.need = need;
this.fileName = fileName;
}
private String content="";
private Integer need;
private String fileName;
public void addContent(int newContext){
content = content + newContext;
if(need < 4){
need++;
}else{
need=1;
}
}
public boolean myNeed(Integer content){
return (content == need)?true:false;
}
public void show(){
System.out.println(fileName+":"+content);
}
}