解决google的多线程面试题

逛论坛的看到一个疑似Google的多线程面试题,觉得挺好玩的,思考了一下。题目如下: 
      启动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);
}
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值