java多线程写文件

// 题目: 多线程写文件

/**

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

		}

	}

}

猜你喜欢

转载自kibear.iteye.com/blog/2388432
今日推荐