题目:有四个线程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...
水平不够,求大神指导。

解决方案 »

  1.   

    我也是刚学一个月。感觉只要重写4个线程的run方法就行了吧?run方法体里面循环写入字母。
    刚学么也别想着 写出多简洁牛逼又能实现功能的代码,   不管怎么样写得怎么样,先实现了再说优化的事
      

  2.   

    不知道题主有没有注意到每个文件里的输出都是有序的。这涉及到线程控制了,通过线程控制使无序的多线程实现有序,推荐使用join()关键字。
      

  3.   

    java.util.concurrent.CountDownLatch
      

  4.   

    今天又想了好久,想出一种解法,贴上代码,请大家指教。package com;import java.io.FileWriter;
    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();
    } }
    }
      

  5.   

    其实很简单 采用thread.join()方法即可实现
    代码片段可见:
    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 ;
    }
    }
      

  6.   

    public class TestThread
    {
        // 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();
            }
        }
    }
      

  7.   


    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;
    }