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。。。没能达到要求,其他线程同步什么的都做出来了 展开
我只能做到写入的时候保证不覆盖前面的,技能还是非常欠缺啊!!!
今天面试,要求创建3个线程,假设线程1的ID为A,线程2为B,线程3为C。各自现在向同一个文件写10遍,要求显示为ABCABCABC....
好久没有笔试了,最后的ABCABCABC。。。没能达到要求,其他线程同步什么的都做出来了 展开
2个回答
展开全部
理论上讲:
如果要让多个线程按顺序执行, 可以用 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
如果要让多个线程按顺序执行, 可以用 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分别代表线程的句柄)
展开全部
创建3个互斥量,a,b,c 初始化时候a不锁,bc锁
线程A循环体
等待获取a
写文件
释放b
锁a
线程B循环体
等待获取b
写文件
释放c
锁b
线程C循环体
等待获取c
写文件
释放a
锁c
这里abc可以用互斥量,信号量,锁,等等实现,含义相同即可
线程A循环体
等待获取a
写文件
释放b
锁a
线程B循环体
等待获取b
写文件
释放c
锁b
线程C循环体
等待获取c
写文件
释放a
锁c
这里abc可以用互斥量,信号量,锁,等等实现,含义相同即可
追问
哈哈!非常感谢.你的逻辑正确。编程就是:使用某种计算机语言实现 现实的逻辑。只要逻辑清楚了,编码就容易多了。
追答
不客气,有帮助就好。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询