多线程中共享变量——CCF总决赛试题
题目要求
数据格式
Q 系统的输入为纯文本格式的文件,由若干行组成,每一行由城市编号、年龄、收入组成,相邻两项之间用一个空格分隔。以下是输入的一个片段:
1001 20 12000
1001 50 24200
1020 30 30000
其中,城市编号是四位数(第一位不为 0),年龄与收入为整数类型。
查询描述
Q 系统需要实现以下三个常用的查询功能:
- Q1: 查询城市 X 某个年龄段的平均收入;
- Q2: 查询城市 X 的收入最高的前 K 位的收入;
- Q3: 分别查询某些城市某一年龄段收入的中位数。
一、下面的程序使用多线程比单线程快了将近一倍。
下面代码简化了输入过程,让输入的数据提前确定好,便于看时间的效率。
import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
class My_Thread implements Runnable{
public File file=new File("src/xian/chen01/city.txt"); /*city.txt中存放数据*/
public BufferedReader reader = null;
public List<Integer> list=null;
public List<Integer> n_list=null; /*List方便排序*/
public int line=0;
public int n_line=0;
public int k=50;
public String x_number="1001";
public String n_number="1001";
public int n_age=20;
public BigInteger age=null;
public int back=0;
public long t1=0;
public My_Thread(){
t1=System.currentTimeMillis();
try{
reader = new BufferedReader(new FileReader(file));
list=new ArrayList<Integer>();
n_list=new ArrayList<Integer>();
age=new BigInteger("0");
}catch(Exception e){}
}
@Override
public void run() {
/*此处代码是核心,加锁避免了java.io.IOException: Stream closed 问题*/
synchronized (this) {
if(back==0)
hui(); /*取出文件的内容*/
else
{ if(back==1)
print(); /*打印结果*/
else
return ;
}
}
}
public synchronized void hui (){
try{
//long t1=System.currentTimeMillis(); String tempString = null;
while ((tempString =reader.readLine())!=null) {
String str[]=tempString.split(" ");
if(x_number.equals(str[0]))
{
age=age.add(new BigInteger(str[1]));
int a=Integer.parseInt(str[2]);
list.add(a);
line ++ ;
}
if(n_number.equals(str[0])&&(n_age+"").equals(str[1]))
{
n_list.add(Integer.parseInt(str[2]));
n_line++;
}
}
reader.close();
back=1;
}catch(Exception e){
System.out.println(e);
}
};
public synchronized void print(){
Comparator<Integer> comparator = new Comparator<Integer>()
{
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1; /*降序*/
}
};
if(line>0)
{
age=age.divide(new BigInteger(line+""));
Collections.sort(list,comparator);
System.out.println("该城市的总人数:"+line);
System.out.println("list的大小:"+list.size());
System.out.println("该城市的平均年龄:"+age);
System.out.print("该城市的前k位收入是:");
for(int i=0;i<k&&i<list.size();++i)
System.out.print(list.get(i)+"、");
System.out.println();
}
else
System.out.println("该城市编号不存在");
/*下面是求某个城市的年龄段的中位数收入*/
System.out.print("编号n城市中位数是:");
if(n_line>0)
{
Collections.sort(n_list,comparator);
if(n_line%2==1)
System.out.println(n_list.get(n_line/2));
else
{
System.out.println((n_list.get(n_line/2)+n_list.get((n_line-1)))/2);
}
}else
System.out.println("编号n城市对应的年龄不存在");
back=2;
System.out.println("时间:"+(System.currentTimeMillis()-t1));
};
};
public class Scoket_Q_City_Query2 {
public static void main(String[] args) throws Exception { My_Thread thread=new My_Thread();
new Thread(thread).start();
new Thread(thread).start();
new Thread(thread).start();
new Thread(thread).start();
new Thread(thread).start();
};
}
运行结果:54毫秒

二、下面是仅仅是一个单线程实现(也可以不建立单线程,只在main主线程实现也可以)
import java.io.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
class MyThread implements Runnable{
@Override
public void run() {
hui();
}
public synchronized void hui (){
try{
long t1=System.currentTimeMillis();
Scanner sc=new Scanner(System.in);
Comparator<Integer> comparator = new Comparator<Integer>()
{
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1; /*降序*/
}
};
System.out.print("输入X城市的编号:");
String x_number=null;
//sc.next();
x_number="1001";
System.out.print("收入X城市的k值:");
int k=50;
//sc.nextInt();
System.out.print("输入某个n城市的编号:");
String n_number="1001";
//sc.next();
System.out.print("输入n城市的某个年龄:");
int n_age=20;
//sc.nextInt();
sc.close();
File file=new File("src/xian/chen01/city.txt");
BufferedReader reader = null;
String tempString = null;
BigInteger age=new BigInteger("0");
int line =0;
int n_line =0;
List<Integer> list=new ArrayList<Integer>();
List<Integer> n_list=new ArrayList<Integer>();
reader = new BufferedReader(new FileReader(file));
while ((tempString =reader.readLine())!=null) {
String str[]=tempString.split(" ");
if(x_number.equals(str[0]))
{
age=age.add(new BigInteger(str[1]));
int a=Integer.parseInt(str[2]);
list.add(a);
line ++ ;
}
if(n_number.equals(str[0])&&(n_age+"").equals(str[1]))
{
n_list.add(Integer.parseInt(str[2]));
n_line++;
}
}
reader.close(); if(line>0)
{
age=age.divide(new BigInteger(line+""));
Collections.sort(list,comparator);
System.out.println("该城市的总人数:"+line);
System.out.println("list的大小:"+list.size());
System.out.println("该城市的平均年龄:"+age);
System.out.print("该城市的前k位收入是:");
for(int i=0;i<k&&i<list.size();++i)
System.out.print(list.get(i)+"、");
System.out.println();
}
else
System.out.println("该城市编号不存在");
/*下面是求某个城市的年龄段的中位数收入*/
System.out.print("中位数是:");
if(n_line>0)
{
Collections.sort(n_list,comparator);
if(n_line%2==1)
System.out.println(n_list.get(n_line/2));
else
{ System.out.println((n_list.get(n_line/2)+n_list.get((n_line-1)/2))/2);
}
}else
System.out.println("编号n城市对应的年龄不存在");
System.out.println("运行时间:"+(System.currentTimeMillis()-t1));
}catch(Exception e){}
};
};
public class Scoket_Q_City_Query {
public static void main(String[] args) throws Exception { MyThread thread=new MyThread();
Thread th=new Thread(thread);
th.start();
};
}
时间:84毫秒

多线程中共享变量——CCF总决赛试题的更多相关文章
- 【多线程】Java线程面试题 Top 50(转载)
Java线程面试题 Top 50 原文链接:http://www.importnew.com/12773.html 本文由 ImportNew - 李 广 翻译自 javarevisited.欢迎 ...
- JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题
JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序猿杜鹏程的博客:http://blog ...
- BlockingQueue阻塞队列(解决多线程中数据安全问题 可用于抢票,秒杀)
案例:一个线程类中 private static BlockingQueue<Map<String, String>> dataQueue = new LinkedBlocki ...
- java多线程中的三种特性
java多线程中的三种特性 原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并 ...
- Java Volatile关键字 以及long,double在多线程中的应用
概念: volatile关键字,官方解释:volatile可以保证可见性.顺序性.一致性. 可见性:volatile修饰的对象在加载时会告知JVM,对象在CPU的缓存上对多个线程是同时可见的. 顺序性 ...
- python 多线程中的同步锁 Lock Rlock Semaphore Event Conditio
摘要:在使用多线程的应用下,如何保证线程安全,以及线程之间的同步,或者访问共享变量等问题是十分棘手的问题,也是使用多线程下面临的问题,如果处理不好,会带来较严重的后果,使用python多线程中提供Lo ...
- 多线程(三)~多线程中数据的可见性-volatile关键字
我们先来看一段代码: ①.线程类,用全局布尔值控制线程是否结束,每隔1s打印一次当前线程的信息 package com.multiThread.thread; publicclassPrintStri ...
- Java多线程中提到的原子性和可见性、有序性
1.原子性(Atomicity) 原子性是指在一个操作中就是cpu不可以在中途暂停然后再调度,既不被中断操作,要不执行完成,要不就不执行. 如果一个操作时原子性的,那么多线程并发的情况下,就不会出 ...
- c#初学-多线程中lock用法的经典实例
本文转载自:http://www.cnblogs.com/promise-7/articles/2354077.html 一.Lock定义 lock 关键字可以用来确保代码块完成运行,而不会被 ...
随机推荐
- 2016 CCPC长春重现赛
1.2016中国大学生程序设计竞赛(长春)-重现赛 2.总结:会做的太少,应变能力也不行,或者说猜题目的能力不行 02 水 04 HDU 5914 Triangle 1.题意:1~n,n个数,问 ...
- Http状态码笔记
1,503 服务器不可用. HTTP Error 503错误的解释:web服务器不能处理HTTP请求,可能是临时超载或者是服务器进行维护.这意味着你需要忍耐一下,等待服务器的临时处理.在这种状态下,一 ...
- Web开发流程
知乎上关于Web开发流程豪情给予的回答 web前端开发流程是什么?进行操作会用到哪些便捷的小工具?是先用模板做好,然后在基础上改吗??正常大家说的改框架是不是指的用模板做的网站原文件?前端开发做的文件 ...
- cxf客户端动态调用空指针异常
异常信息如下: 二月 , :: 上午 org.apache.cxf.common.jaxb.JAXBUtils logGeneratedClassNames 信息: Created classes: ...
- Windows2003远程桌面单会话登录
在使用远程桌面连接到Windows2003的时候默认设置是同一用户可以进行多会话登录. (在winxp.win7及以后版本的windows中已经变成单会话登录.) 同用户多会话登录在管理上带来诸多麻烦 ...
- 10个jQuery小技巧
收集的10个 jQuery 小技巧/代码片段,可以帮你快速开发. 1.返回顶部按钮 你可以利用 animate 和 scrollTop 来实现返回顶部的动画,而不需要使用其他插件. $('a.top' ...
- spawn协程学习
对于IO密集型的程序,一般比较高效的做法是选择异步来实现,因为使用异步的方法更容易写出高效的程序.然而使用异步的话,经验较少的人往往会使自己的程序结构变得很混乱,进而导致程序的可读性变差.记得有人说过 ...
- 双十二前夕爆京东12G数据泄露的真相是什么
今天早上手机上推送出京东12g数据泄漏的消息,随即搜了下网上的相关新闻,感觉舆论又一次的干了一件惊天地的事情,到底京东的哪所谓的12G的用户信息数据有没有泄漏?舆论为什么齐刷刷的在12月11日突然间爆 ...
- Thinking in Java——笔记(18)
I/O The original byte-oriented library was supplemented with char-oriented, Unicode-based I/O classe ...
- 数据结构与算法C++描述学习笔记1、辗转相除——欧几里得算法
前面学了一个星期的C++,以前阅读C++代码有些困难,现在好一些了.做了一些NOI的题目,这也是一个长期的目标中的一环.做到动态规划的相关题目时发现很多问题思考不通透,所以开始系统学习.学习的第一本是 ...