主要问题出现在public int index = 1;变量对多个线程共享 有可能出现线程1访问的时候这个变量值是1,线程2访问的时候还是1,因为你线程执行并不是同步的 1、可以象一楼说的那样给index加个同步,但是要把doWork中的index++去掉 2、还可以给这个doWork加个synchronized修饰符(这个保证是有序的)
改成这样就没问题了public class T { public static final int THREAD_SIZE = 4; public Thread[] pool; public BlockingQueue<Integer> producer = new LinkedBlockingQueue<Integer>(); public String path = "D:/"; public int index = 1; public T() { this(THREAD_SIZE); } public T(int size) { pool = new Thread[size]; Writer writer = new Writer(); for (int i = 0; i < size; i++) { pool[i] = new Thread(writer, "thread" + i); pool[i].start(); } } private class Writer implements Runnable { public void run() { int temp = 0; try { while ((temp = producer.take()) != 0) { doWork(temp); } producer.put(0); } catch (Exception e) { e.printStackTrace(); } } public void doWork(int num) { BufferedWriter out = null; try { out = new BufferedWriter(new FileWriter(path + num + ".txt")); out.write(String.valueOf(num)); out.flush(); System.out.println(num); } catch (IOException e) { e.printStackTrace(); } finally { if(null != out) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } } } public void addProducer(int num) throws Exception { for (int i = 1; i <= num; i++) { producer.put(i); } producer.put(0); } public static void main(String[] args) throws Exception { T instance = new T(THREAD_SIZE); instance.addProducer(100); } }
package testproject;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.concurrent.*;public class MutiWriter { public static final int threadSize = 4;
public volatile boolean running = false;
public Thread[] pool;
public BlockingQueue<Integer> producer = new LinkedBlockingQueue<Integer>();
public String path;
public int index = 1; public MutiWriter() {
this(threadSize);
} public MutiWriter(int size) {
pool = new Thread[size];
Writer writer = new Writer();
for (int i = 0; i < size; i++) {
pool[i] = new Thread(writer, "thread" + i);
pool[i].start();
}
running = true;
} private class Writer implements Runnable { public void run() {
int temp = 0;
try {
while ((temp = producer.take()) != 0) {
doWork(temp);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
producer.put(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public void doWork(int num) {
// System.out.println("ThreadNow " + Thread.currentThread().getName());
try {
BufferedWriter out = new BufferedWriter(new FileWriter(path + getIndex() + ".txt"));
out.write(String.valueOf(num));
out.flush();
out.close();
System.out.println(index);
} catch (IOException e) {
e.printStackTrace();
}
index++;
}
}
// 这里需要同步
synchronized int getIndex(){
int idx=this.index;
this.index++;
return idx;
} public void addProducer(int num) {
for (int i = 1; i < num; i++) {
try {
producer.put(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public void shutdown() {
if (running) {
running = false;
}
try {
producer.put(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public void waitting() {
if (running || !producer.contains(0)) {
throw new IllegalStateException("shutdown first");
}
try {
producer.put(0);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
for (Thread t : pool) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public static void main(String[] args) {
MutiWriter instance = new MutiWriter(threadSize);
instance.addProducer(101);
instance.shutdown();
instance.waitting();
}
}
然后取数据是index.get()
+1换成index.incrementAndGet()
有可能出现线程1访问的时候这个变量值是1,线程2访问的时候还是1,因为你线程执行并不是同步的
1、可以象一楼说的那样给index加个同步,但是要把doWork中的index++去掉
2、还可以给这个doWork加个synchronized修饰符(这个保证是有序的)
public Thread[] pool;
public BlockingQueue<Integer> producer = new LinkedBlockingQueue<Integer>();
public String path = "D:/";
public int index = 1; public T() {
this(THREAD_SIZE);
} public T(int size) {
pool = new Thread[size];
Writer writer = new Writer();
for (int i = 0; i < size; i++) {
pool[i] = new Thread(writer, "thread" + i);
pool[i].start();
}
} private class Writer implements Runnable { public void run() {
int temp = 0;
try {
while ((temp = producer.take()) != 0) {
doWork(temp);
}
producer.put(0);
} catch (Exception e) {
e.printStackTrace();
}
} public void doWork(int num) {
BufferedWriter out = null;
try {
out = new BufferedWriter(new FileWriter(path + num + ".txt"));
out.write(String.valueOf(num));
out.flush();
System.out.println(num);
} catch (IOException e) {
e.printStackTrace();
} finally {
if(null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
} public void addProducer(int num) throws Exception {
for (int i = 1; i <= num; i++) {
producer.put(i);
}
producer.put(0);
} public static void main(String[] args) throws Exception {
T instance = new T(THREAD_SIZE);
instance.addProducer(100);
}
}