3个线程同时写一个文件, 第一个写入A,第二个写入B,第三个C,如何保证文件内容为ABC

3个线程同时写一个文件,第一个写入A,第二个写入B,第三个C,如何保证文件内容为ABCABC...我只能做到写入的时候保证不覆盖前面的,技能还是非常欠缺啊!!!今天面试,... 3个线程同时写一个文件, 第一个写入A,第二个写入B,第三个C,如何保证文件内容为ABCABC...
我只能做到写入的时候保证不覆盖前面的,技能还是非常欠缺啊!!!
今天面试,要求创建3个线程,假设线程1的ID为A,线程2为B,线程3为C。各自现在向同一个文件写10遍,要求显示为ABCABCABC....
好久没有笔试了,最后的ABCABCABC。。。没能达到要求,其他线程同步什么的都做出来了
展开
 我来答
菜农阿米
2013-08-17 · 超过24用户采纳过TA的回答
知道答主
回答量:33
采纳率:0%
帮助的人:41.3万
展开全部
理论上讲:
如果要让多个线程按顺序执行, 可以用 Thread 类的join()方法, 比如:
statementA....
threadA.join();
statementB....
那么, 只有等threadA执行完之后, statementB语句才能得到执行。

用在你的问题上, 需要解决两个问题:
1、 要让A B C 按顺序执行: 解决之道,需要在B线程开始执行的时候调用A.join(), 让A先执行;在C线程开始执行的时候调用B.join()让B先执行。 这样, 就保证了A B C按顺序执行。
2、 解决输出: 在A执行的时候, 需要把A全部输出,B与C的位置先用null占位;A执行完之后, 输出结果为: A null null A null null A null null A null null ................; 在B执行的时候, 把A线程执行的结果替换成 A B null A B null A B null........; 在C 执行的时候, 把B线程执行的结果替换成: A B C A B C A B C A B C.......。
解决了以上两个问题之后,该问题迎刃而解。

输出文件的时候, 用单独的线程用来输出, 只需要在该线程中 把 线程C join()就可以了, 这样, 该线程就等待C执行完后才能输出。

附上代码:
package com.sequence;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.List;

public class MyWriteFile {

/**
* 线程A
* @author Administrator
*
*/
private static final class A extends Thread{

private List<String> list;
public A(List<String> list){
this.list = list;
}

@Override
public void run() {
for(int i=0; i<30; i+=3){
list.add(i, "A");
// 将B和C线程输出的地方占位
list.add(i+1, null);
list.add(i+2, null);
}
}
}

/**
* 线程B
* @author Administrator
*
*/
private static final class B extends Thread{

private Thread myA;
private List<String> list;
public B(Thread myA, List<String> list){
this.myA = myA;
this.list = list;
}

@Override
public void run() {
try {
myA.join(); //线程B在此处阻塞, 等待A线程执行完才能继续
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=1; i<30; i+=3){
list.set(i, "B");
}
}
}

/**
* 线程C
* @author Administrator
*
*/
private static final class C extends Thread{
private List<String> list;
private Thread myB;
public C(Thread myB, List<String> list){
this.myB = myB;
this.list = list;
}

@Override
public void run() {
try {
myB.join(); //线程C在此处阻塞, 等待B线程执行完才能继续
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=2; i<30; i+=3){
list.set(i, "C");
}
}
}

/**
* 负责输出的线程
* @author Administrator
*
*/
private static final class Output extends Thread{
private List<String> list;
private Thread myC;
public Output(Thread myC, List<String> list){
this.myC = myC;
this.list = list;
}

@Override
public void run() {
try {
myC.join(); //负责输出的线程在此处阻塞, 等待C线程执行完才能继续
} catch (InterruptedException e) {
e.printStackTrace();
}

// 输出到文件
File file = new File("D:\\output.txt");
BufferedWriter sb = null;
try {
sb = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
for(String str : list){
sb.write(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
} finally{
try {
sb.close(); // 最后别忘了关闭流
} catch (IOException e) {
e.printStackTrace();
}
}

}
}

public static void main(String[] args) {

// 四个线程启动
List<String> list = new LinkedList<String>();
Thread a = new A(list);
Thread b = new B(a, list);
Thread c = new C(b, list);
Thread output = new Output(c, list);
a.start();
b.start();
c.start();
output.start();
}

}

打开文件之后, 结果为: ABCABCABCABCABCABCABCABCABCABC
追问
你好,感谢回答!请问如果打印的内容是线程句柄本身怎么弄?比如线程1写入的是线程1的句柄。。。。然后感觉您的方法也许有缺点:比如第二次要开始执行线程3的时候,程序挂了,然后看写入的文件
:AB NULL AB NULL...(?没仔细理解你的代码,java有心情的时候耐心才可以看懂,我c++熟悉一点)
按照题目的要求,文件内容是:
ABCAB(ABC分别代表线程的句柄)
ddbird
2013-08-19 · 超过17用户采纳过TA的回答
知道答主
回答量:75
采纳率:0%
帮助的人:16.5万
展开全部
创建3个互斥量,a,b,c 初始化时候a不锁,bc锁
线程A循环体
等待获取a

写文件

释放b

锁a

线程B循环体
等待获取b

写文件

释放c

锁b

线程C循环体
等待获取c

写文件
释放a

锁c

这里abc可以用互斥量,信号量,锁,等等实现,含义相同即可
追问
哈哈!非常感谢.你的逻辑正确。编程就是:使用某种计算机语言实现 现实的逻辑。只要逻辑清楚了,编码就容易多了。
追答
不客气,有帮助就好。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式