欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java多线程写文件  

程序员文章站 2022-03-20 17:22:23
...

 

// 题目: 多线程写文件

/**

有四个线程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();
				}
			}

		}

	}

}