多线程中共享变量——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 关键字可以用来确保代码块完成运行,而不会被 ...
随机推荐
- 团队Git工作流总结
为什么使用Git “svn用了这么多年都好好的,为啥折腾搞Git?” “Git一点都不好用,提交个代码都提交不上去!” “Git这么复杂,命令多到记不住,而且完全用不到.哪有svn简单好用?” 推 ...
- 【BZOJ】3991: [SDOI2015]寻宝游戏
题意 给一个\(n\)个点带边权的树.有\(m\)次操作,每一次操作一个点\(x\),如果\(x\)已经出现,则\(x\)消失.否则\(x\)出现.每一操作后,询问从某个点开始走,直到经过所有出现的点 ...
- Python中的高级特性
1.切片.使用“[”和“]”即可,类似Matlab,可以切list,tuple,字符串等. 2.迭代.Python内置的enumerate函数可以把一个list变成索引-元素对. 3.列表生成式.列表 ...
- jsonp模拟获取百度搜索相关词汇
随便写了个jsonp模拟百度搜索相关词汇的小demo,帮助新手理解jsonp的用法. <!DOCTYPE html><html lang="en">< ...
- SpringMVC核心分发器DispatcherServlet分析[附带源码分析]
目录 前言 DispatcherServlet初始化过程 DispatcherServlet处理请求过程 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不 ...
- Web用户的身份验证及WebApi权限验证流程的设计和实现
5. WebApi 服务端代码示例 5.1 控制器基类ApiControllerBase [csharp] view plaincopy /// /// Controller的基类,用于实现适合业 ...
- Django框架初入
一.Django 特性 数据库功能强大(利用python的类继承,几行代码就可以实现一个动态的数据库操作接口(API)) 强大的后台功能 优雅的网址(正则匹配网址,传递到对应函数) 模板与缓存系统 二 ...
- ps 文字处理篇
ps文字处理篇 1.对文字镂空处理并且移除到新图像上: 首先创建图层-文字编辑-横排编辑 其次 魔棒工具选择通过颜色来选择选区 右击图层-栅格化图层 删除键将选择的颜色删除留下选区- 复制粘贴到另一个 ...
- Java实现Oracle数据库备份
今天将很早就实现的一个Oracle数据库备份功能粘贴出来,这个功能是在大学做阶段设计时写的: import java.io.File; import java.io.IOException; /** ...
- Apache增加Basic Auth
在.htaccess文件中增加 AuthUserFile /var/www/htpasswd/test.htpasswd AuthName EnterPassword AuthType Basic r ...