java multithreading file writing

 

// Topic: Multithreading to write files

/**

There are four threads 1, 2, 3, 4. The function of thread 1 is to output A, the function of thread 2 is to output B, and so on...

There are now four files file1, file2, file3, file4. Initially empty.

Now let's make the four files look like this:

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....

**/

 

My train of thought:

1. Each thread records the order in which it wants to write files, and starts from scratch after writing all files.

2. There is something similar to thread scheduling, where threads are executed in order, and then all threads are executed from scratch.

3. When each thread executes, it needs to update the file that it writes next time. If it is finished, it will start over again.

4. After each thread is executed, the next thread to be executed in the thread scheduling needs to be updated.

 

The following code is written in a sloppy manner, without any comments, and some unnecessary codes are not organized.

 

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 {
    // thread id to write next
	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) {
			  // If not equal, the current thread does not need to write to other threads
              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;
					// reset if greater than 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 ();
					}
					// wake up all threads
					lock.notifyAll();
				}
			}

		}

	}

}

   

 

   The following is the improved code, much clearer than the above.

 

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();

	}

}

/**
 * schedule thread
 */
class ThreadSchedule {
	public int willRunThreadId = 1;
	
	public final int threadCount = 4;
}

/**
 * write tasks
 */
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;
	// thread id
	private final int id;
	// characters to write
	private final String ch;
	// write the number of the file
	private final int[] fileNos;
	// total number of files
	private final int countFile = 4;
	// The number of the file currently being written
	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("thread" + id + " writing" + "file" + fileNos[currfileNo] + " ");
					
					TimeUnit.SECONDS.sleep(1);
					
					fw = new FileWriter("file" + fileNos[currfileNo], true);
					fw.write(ch);
					if (++currfileNo == countFile)
						currfileNo = 0;
					// reset if greater than 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 ();
					}
					// wake up all threads
					lock.notifyAll();
				}
			}

		}

	}

}

 

 

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327011768&siteId=291194637