java网易笔试题--线程

import java.io.*;
import java.util.*;

/**
 * 一个文件中有10000个数,用Java实现一个多线程程序将这个10000个数输出到5个不用文件中(不要求输出到每个文件中的数量相同)。
 * 要求启动10个线程,两两一组,分为5组。每组两个线程分别将文件中的奇数和偶数输出到该组对应的一个文件中,
 * 需要偶数线程每打印10个偶数以后,就将奇数线程打印10个奇数,如此交替进行。
 * 同时需要记录输出进度,每完成1000个数就在控制台中打印当前完成数量,并在所有线程结束后,在控制台打印”Done”.
 * */
public class Main{
    public static void main(String[] args){
        try{
            PrintWriter pw = new PrintWriter(new FileWriter(new File("input.txt")),true);
            Random random = new Random();
            for(int i = 0;i < 10000;i++){
                pw.print(Math.abs(random.nextInt()) % 100 + " ");
            }
            pw.flush();
            pw.close();
            BufferedReader reader = new BufferedReader(new FileReader("input.txt"));
            String str = reader.readLine();
            reader.close();
            String[] strs = str.split(" ");
            int j = 0;
            for(int i = 0;i < 5;i++){
                int[] records = new int[2000];
                for(int k = 0;k < 2000;k++){
                    records[k] = Integer.parseInt(strs[j]);
                    j++;
                }
                PrintWriter writer = new PrintWriter(new FileWriter(new File("output" + i + ".txt")),true);
                ThreadGroup group = new ThreadGroup(records,writer);
                new Thread(group).start();
                new Thread(group).start();
            }

        }catch (Exception e){
            e.printStackTrace();
        }

    }

}
class ThreadGroup implements Runnable{
    private static int count = 0;
    //所有ThreadGroup类对象共享一个锁,用于count变量的同步,任何一个线程需要修改count变量,必须取到该锁
    private static Object lock = new Object();
    public static final int EVEN = 0;//代表偶数
    public static final int ODD = 1;//代表奇数

    private int type;
    private int records[];
    private PrintWriter writer;
    private int oddPoint = 0;//记录每次打印奇数的起始位置
    private int evenPoint = 0;//记录每次打印偶数的起始位置

    public ThreadGroup(){

    }
    public ThreadGroup(int[] records,PrintWriter ps){
        this.records = records;
        this.writer = ps;
        this.type = EVEN;
    }

    @Override
    public void run() {
        while(print());
    }

    private synchronized boolean print(){
        for(int i = 0;i < 10;){
            //如果奇数和偶数都打印完成之后,就直接停止打印,等待该线程自己结束
            if(oddPoint >= records.length && evenPoint >= records.length){
                notifyAll();
                return false;
            }

            //如果该线程该打印奇数,但奇数已经打印完了就直接停滞本次10个数的打印
            //偶数同理,等下一次切换类型后再开始打印
            if((oddPoint >= records.length && type == ODD) || (evenPoint >= records.length && type == EVEN)) {
                break;
            }

            if(type == EVEN){
                if(records[evenPoint] % 2 == 0){
                    i++;
                    writer.print(records[evenPoint] + "  ");
                    writer.flush();
                    //锁定全局变量方便线程输出后计数
                    synchronized (lock){
                        count++;
                        if(count % 1000 == 0){
                            System.out.println("当前完成数量:" + count);
                            if(count == 10000){
                                System.out.println("Done!");
                            }
                        }
                    }
                }
                evenPoint++;
            }else{
                if(records[oddPoint] % 2 == 1){
                    i++;
                    writer.print(records[oddPoint] + " ");
                    writer.flush();
                    synchronized(lock){
                        count++;
                        if(count % 1000 == 0){
                            System.out.println("当前完成数量" + count);
                            if(count == 10000){
                                System.out.println("Done!");
                            }
                        }
                    }
                }
                oddPoint++;
            }
        }
        type = ~type;//切换打印类型
        notifyAll();    //一组中的任意线程打印完后唤醒另一个线程
        try{
            wait();     //释放锁进行等待状态,等待另一线程打印完
        }catch (Exception e){
            e.printStackTrace();
        }
        return true;
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值