题目:有四个线程A、B、C、D,线程A的功能是打印出A,线程B的功能是打印出B,以此类推。。
现在有四个txt文件A.TXT、B.TXT、C.TXT、D.TXT,初始都为空。
每个线程都分别将输出结果写入4个文件,要求格式如下:
A.TXT:A B C D A B C D...
A.TXT: B C D A B C D A...
C.TXT: C D A B C D A B...
D.TXT: D A B C D A B C...
水平不够,求大神指导。
现在有四个txt文件A.TXT、B.TXT、C.TXT、D.TXT,初始都为空。
每个线程都分别将输出结果写入4个文件,要求格式如下:
A.TXT:A B C D A B C D...
A.TXT: B C D A B C D A...
C.TXT: C D A B C D A B...
D.TXT: D A B C D A B C...
水平不够,求大神指导。
解决方案 »
- 想做个java小项目练习下J2SE,请高人指点
- AbstractList.this.remove(lastRet) 中的AbstractList.this是什么含义,他是在调用哪个类的remove方法
- Java 反射问题
- 学JAVA10来天,写了个计算器!但是感觉布局不好,请指教!
- 奇怪还是少见多怪!?
- load图像文件的几个问题
- 老是出现同样的错误!急死了!在线等!
- 简单问题 JDK1。3在win98下怎么设置路径 我放在c根目录下的 请详细一点~
- 哪里可以下载IBM提供的JNDI的服务程序?
- scjp的考试中都是以选择题的形式出现的吗?
- 隐式参数this和super是如何实现的
- 静态测试麻烦看下是bug还是false positive可以吗大神!
刚学么也别想着 写出多简洁牛逼又能实现功能的代码, 不管怎么样写得怎么样,先实现了再说优化的事
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class Problem {
public void appendMethod(String fileName, String content) {
try {
// 打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
FileWriter writer = new FileWriter(fileName, true);
writer.write(content);
writer.close();
} catch (IOException e) {
e.printStackTrace();
} }
public static void main(String[] args) {
String A = "A";
String B = "B";
String C = "C";
String D = "D";
String[] contexts = new String[4];
contexts[0] = A;
contexts[1] = B;
contexts[2] = C;
contexts[3] = D;
String pre = "E:\\thread\\";
String suf = ".txt";
String[] fileNames = new String[4];
List<ArrayBlockingQueue<String>> queues = new ArrayList<ArrayBlockingQueue<String>>();
//数组有泛型问题,不好用。
// ArrayBlockingQueue<?>[] queues = new ArrayBlockingQueue<?>[4];
for (int i = 0; i < contexts.length; i++) {
String fileName = pre + contexts[i] + suf;
fileNames[i] = fileName;
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<String>(
contexts.length);
try {
queue.put(fileName);
} catch (InterruptedException e) {
}
queues.add(queue);
}
for (int i = 0; i < contexts.length; i++) {
ArrayBlockingQueue<String> producet;
if ((i + 1) == contexts.length) {
producet = queues.get(0);
} else {
producet = queues.get(i + 1);
}
new Thread(new R(contexts[i], producet, queues.get(i))).start();
}
}
}class R implements Runnable {
String context;
BlockingQueue<String> producet;
BlockingQueue<String> consumer;
public R(String context, BlockingQueue<String> producet,
BlockingQueue<String> consumer) {
this.context = context;
this.producet = producet;
this.consumer = consumer;
}
public void run() {
try {
Problem p = new Problem();
for (int i = 0; i < 100; i++) {
String fileName = consumer.take();
p.appendMethod(fileName, context);
producet.put(fileName);
}
} catch (InterruptedException e) {
e.printStackTrace();
} }
}
代码片段可见:
package com.jing.test.thread;import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
/**
* 打印线程类
* @author jtj
*
*/
public class PrintRun implements Runnable { private String printStr ;
private String fileName ;
public PrintRun(String printStr,String filename) {
this.printStr = printStr ;
this.fileName = filename ;
}
@Override
public void run() {
BufferedWriter writer = null ;
File file = new File(this.fileName) ;
try {
if(!file.isFile()){
file.createNewFile() ;
}
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true))) ;
writer.write(printStr);
System.err.println(fileName + "存放的数据有: " +printStr);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
writer.flush();
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}}
------------------------------华丽的分割线--------------------------------
package com.jing.test.thread;import java.util.List;
/**
* 操作打印线程类的主类
* @author jtj
*
*/
public class ExecuteRun implements Runnable {
//将打印线程的类装到该集合中
List<Runnable> threadList ;
public ExecuteRun(List<Runnable> list) {
this.threadList = list ;
}
@Override
public void run() {
int size = threadList.size() ;
for(int i = 0; i < size; i++){
Runnable runnable = threadList.get(i) ;
Thread printThread = new Thread(runnable) ;
printThread.start();
try {
//等待该线程完成再往下执行
printThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}}
--------------------------------------华丽的分割线----------------------------------------
package com.jing.test.thread;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;public class MainRun { public static void main(String[] args){
String[] aCodes = {"A","B","C","D"} ;
String[] bCodes = {"B","C","D","A"} ;
String[] cCodes = {"C","D","A","B"} ;
String[] dCodes = {"D","A","B","C"} ;
new Thread(new ExecuteRun(MainRun.addCollections(aCodes, "src/com/jing/resources/a.txt"))).start() ;
new Thread(new ExecuteRun(MainRun.addCollections(bCodes, "src/com/jing/resources/b.txt"))).start() ;
new Thread(new ExecuteRun(MainRun.addCollections(cCodes, "src/com/jing/resources/c.txt"))).start() ;
new Thread(new ExecuteRun(MainRun.addCollections(dCodes, "src/com/jing/resources/d.txt"))).start() ;
}
/**
* 装打印线程集合方法
* @param codes 打印线程的先后顺序数组
* @param filename 输出的文件名
* @return
*/
public static List<Runnable> addCollections(String[] codes,String filename){
List<Runnable> list = new ArrayList<>() ;
int size = codes.length ;
for(int i = 0; i < size; i++){
Runnable runnable = new PrintRun(codes[i], filename) ;
list.add(runnable) ;
}
return list ;
}
}
{
// private static final Log LOGGER = LogFactory.getLog(TestThread.class); public static void main(String[] args)
{ Runnable runnableA = new Runnable()
{
public void run()
{
int i = 0;
while (i < 10)
{
writeA();
writeB();
writeC();
i++;
}
System.out.println();
}
};
Runnable runnableB = new Runnable()
{
public void run()
{
int i = 0;
while (i < 10)
{
writeA();
writeB();
writeC();
i++;
}
System.out.println();
}
};
Runnable runnableC = new Runnable()
{
public void run()
{
int i = 0;
while (i < 10)
{
writeA();
writeB();
writeC();
i++;
}
System.out.println();
}
}; Thread threadA = new Thread(runnableA);
Thread threadB = new Thread(runnableB);
Thread threadC = new Thread(runnableC); threadA.start();
threadB.start();
threadC.start();
} static String flagA = "A";
static String flagB = "B";
static String flagC = "C"; private static void writeA()
{
ReentrantLock lock = new ReentrantLock();
try
{
lock.lock();
if (flagA.equals("A"))
{
System.out.print("A");
flagA = "B";
}
} finally
{
lock.unlock();
}
} private static void writeB()
{
ReentrantLock lock = new ReentrantLock();
try
{
lock.lock();
if (flagB.equals("B"))
{
System.out.print("B");
flagA = "C";
}
} finally
{
lock.unlock();
}
} private static void writeC()
{
ReentrantLock lock = new ReentrantLock();
try
{
lock.lock();
if (flagC.equals("C"))
{
System.out.print("C");
flagA = "A";
}
} finally
{
lock.unlock();
}
}
}
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Condition;import java.io.IOException;import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import static java.nio.file.StandardOpenOption.*;import java.nio.channels.WritableByteChannel;
import java.nio.ByteBuffer;public class Test{
public static void main(String[] args){
String[] strs = {"A","B","C","D"};//设置写入的内容.可以无限添加长度和调整顺序
Path file = Paths.get(System.getProperty("user.dir")).resolve("A.txt");
int length = strs.length;
int time = 100;//这里设置每个内容写入的次数.
Group group = new Group(file,strs);
Thread[] threads = new Thread[length];
for(int i = 0 ; i < length ; i ++){
threads[i] = new Thread(new Task(group,i,time));
} for(int i = 0 ; i < length ; i ++){
threads[i].start();
}
}
}class Group{
public Group(Path file,String ... contents){
assert (Files.notExists(file) || Files.isRegularFile(file));
try{
channel = Files.newByteChannel(file,CREATE,WRITE,APPEND);
}catch(IOException e){
e.printStackTrace();
System.exit(1);
}
this.length = contents.length;
conditions = new Condition[length];
this.contents = contents;
for(int i = 0 ; i < length ; i ++){
conditions[i] = lock.newCondition();
}
lives = new boolean[length];
lives[0] = true;
} public void process(int index){ if(firstTimeWait){//首次让第一个线程睡眠,腾出时间让第二个线程启动.
firstTimeWait = false;
try{
Thread.sleep(100);
}catch(InterruptedException e){
e.printStackTrace();
}
}
try{
lock.lock();
assert index >= 0 && index < length;
if(!lives[index]){
conditions[index].await();
}
lives[index] = false;
try{
Thread.sleep(10);//这里需要设置等待.要不有时候处理太快会出现死锁.
}catch(InterruptedException e){
e.printStackTrace();
}
channel.write(ByteBuffer.wrap(contents[index].getBytes())); if(index == length - 1){
conditions[0].signalAll();
}else{
conditions[index + 1].signalAll();
} lock.unlock();
}catch(InterruptedException|IOException e){
e.printStackTrace();
System.exit(1);
}
} public int getLength(){
return length;
}
private final ReentrantLock lock = new ReentrantLock();
private final Condition[] conditions;
private boolean[] lives;
private final String[] contents;
private final int length;
private WritableByteChannel channel;
private boolean firstTimeWait = true;
}class Task implements Runnable{
public Task(Group group,int index,int time){
this.group = group;
this.index = index;
assert index < group.getLength();
this.time = time;
} @Override
public void run(){
for(int i = 0 ; i < time ; i ++){
group.process(index);
if(i == time - 1){
Thread.currentThread().interrupt();
}
}
} private Group group;
private int index;
private int time;
}