java多线程写文件
程序员文章站
2022-03-20 17:22:35
...
// 题目: 多线程写文件
/**
有四个线程1、2、3、4。线程1的功能就是输出A,线程2的功能就是输出B,以此类推.........
现在有四个文件file1,file2,file3, file4。初始都为空。
现要让四个文件呈如下格式:
file1:A B C D A B....
file2:B C D A B C....
file3:C D A B C D....
file4:D A B C D A....
**/
我的思路:
1.每个线程记录自己要写入文件的顺序,写完一遍所有文件以后又从头来。
2.有个类似线程调度的东西,这里面按顺序执行线程,执行完所有线程以后又从头来。
3.每个线程执行的时候,要更新自己下一次写入的文件,如果写完一遍又从头来。
4.每个线程执行完以后,需要更新线程调度里面下一个要执行的线程。
下面的代码,写的比较潦草,也没有写什么注释,有些不必要的代码也没有整理。
import java.io.FileWriter; import java.io.IOException; public class ThreadApp { public static void main(String[] args) { final Re r = new Re(); WriteTask t1 = new WriteTask(1, 1, "A", new int[] { 1, 4, 3, 2 }, r); WriteTask t2 = new WriteTask(2, 2, "B", new int[] { 2, 1, 3, 4 }, r); WriteTask t3 = new WriteTask(3, 3, "C", new int[] { 3, 2, 1, 4 }, r); WriteTask t4 = new WriteTask(4, 4, "D", new int[] { 4, 3, 2, 1 }, r); new Thread(t1).start(); new Thread(t2).start(); new Thread(t3).start(); new Thread(t4).start(); } } class Re { // 下一个写入的线程id public volatile int nextThread = 1; } class WriteTask implements Runnable { // 1 - file1 file4 file3 file2 // 2 - file2 file1 file3 file4 // 3 - file3 file2 file1 file4 // 4 - file4 file3 file2 file1 // private volatile boolean stop = false; private Re lock; // private final int id; private final String ch; private final int[] fileNos; private int currfileNos; public WriteTask(int id, int nextThread, String ch, int[] fileNos, Re lock) { this.id = id; this.ch = ch; this.fileNos = fileNos; this.lock = lock; } @Override public void run() { while (!stop) { synchronized (lock) { // 如果不相等 表示当前线程不需要写入 让给其他线程 while (id != lock.nextThread) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } if (currfileNos == 4) currfileNos = 0; FileWriter fw = null; try { fw = new FileWriter("file" + fileNos[currfileNos], true); fw.write(ch); if (++currfileNos > 3) currfileNos = 0; // 如果大于4了则重置 if (++lock.nextThread > 4) lock.nextThread = 1; } catch (IOException e) { e.printStackTrace(); stop = true; } finally { try { if (null != fw) fw.close(); } catch (IOException e) { e.printStackTrace(); } // 唤醒所有的线程 lock.notifyAll(); } } } } }
下面的是改进的代码,比上面的清楚很多了。
import java.io.FileWriter; import java.io.IOException; import java.util.concurrent.TimeUnit; public class ThreadApp { public static void main(String[] args) { final ThreadSchedule r = new ThreadSchedule(); WriteTask t1 = new WriteTask(1, "A", new int[] { 1, 4, 3, 2 }, r); WriteTask t2 = new WriteTask(2, "B", new int[] { 2, 1, 3, 4 }, r); WriteTask t3 = new WriteTask(3, "C", new int[] { 3, 2, 1, 4 }, r); WriteTask t4 = new WriteTask(4, "D", new int[] { 4, 3, 2, 1 }, r); new Thread(t1).start(); new Thread(t2).start(); new Thread(t3).start(); new Thread(t4).start(); } } /** * 调度线程 */ class ThreadSchedule { public int willRunThreadId = 1; public final int threadCount = 4; } /** * 写任务 */ class WriteTask implements Runnable { // 1 - file1 file4 file3 file2 // 2 - file2 file1 file3 file4 // 3 - file3 file2 file1 file4 // 4 - file4 file3 file2 file1 // private volatile boolean stop = false; private ThreadSchedule lock; // 线程id private final int id; // 写入的字符 private final String ch; // 写入文件的编号 private final int[] fileNos; // 总文件数 private final int countFile = 4; // 当前正要写入的文件编号 private int currfileNo; public WriteTask(int id, String ch, int[] fileNos, ThreadSchedule lock) { this.id = id; this.ch = ch; this.fileNos = fileNos; this.lock = lock; } @Override public void run() { while (!stop) { synchronized (lock) { while (id != lock.willRunThreadId) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } FileWriter fw = null; try { System.out.println("线程 " + id + " 正在写入 " +"file" + fileNos[currfileNo] + " "); TimeUnit.SECONDS.sleep(1); fw = new FileWriter("file" + fileNos[currfileNo], true); fw.write(ch); if (++currfileNo == countFile) currfileNo = 0; // 如果大于4了则重置 if (++lock.willRunThreadId > lock.threadCount) lock.willRunThreadId = 1; } catch (IOException e) { e.printStackTrace(); stop = true; } catch (InterruptedException e) { e.printStackTrace(); } finally { try { if (null != fw) fw.close(); } catch (IOException e) { e.printStackTrace(); } // 唤醒所有的线程 lock.notifyAll(); } } } } }
上一篇: Apache Geode 属性设置