解决方案 »

  1.   

    这是一个典型的多线程同步问题,因为对index共享资源做++操作没有同步导致的,改进代码如下:
    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();
        }
    }
      

  2.   

    把index变量换成AtomicInteger类型的即可
    然后取数据是index.get()
    +1换成index.incrementAndGet()
      

  3.   

    主要问题出现在public  int  index = 1;变量对多个线程共享
    有可能出现线程1访问的时候这个变量值是1,线程2访问的时候还是1,因为你线程执行并不是同步的
    1、可以象一楼说的那样给index加个同步,但是要把doWork中的index++去掉
    2、还可以给这个doWork加个synchronized修饰符(这个保证是有序的)
      

  4.   

    改成这样就没问题了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);
    }
    }