好的,对于我在CSC330类中的项目,我应该使用线程快速找到大量数据集中查询的答案。数组中的每个项目都是用户,字符串是他们在由数字标识的网站上访问的网站的集合。
示例(数组是String users [])
用户[1] =“1 4 5 7”用户[2] =“1 2 7 17 10”用户[3] =“6”
查询是:
此阵列中有大约一百万用户,我们必须在没有线程的情况下解决以下查询,而不是用于测试的较小规模版本的数据。我的所有工作。现在我需要切换到海量文本文件,我需要使用线程来提高速度。我想知道哪里有益,以及我如何实现这些线程。我将提供用于解决每个查询的代码。我想我可以使用多个线程同时遍历数组的各个部分,但我不知道如何执行它。
public boolean query1(String num, String pageName){
if(num == null){
return false;
}
else
{
int userCount = 0;
int pageNum = convert(pageName);
System.out.println(pageNum);
String pageNumString = Integer.toString(pageNum);
System.out.println(pageNumString);
for(int i = 0; i < users.length; i++ )
{
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString))
{
userCount++;
break;
}
}
}
if(userCount > Integer.parseInt(num)){
return false;
}
else{
return true;
}
}
}
public float query2(String pageName){
int userCount = 0;
int pageNum = convert(pageName);
String pageNumString = Integer.toString(pageNum);
for(int i = 0; i < users.length; i++ )
{
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString))
{
userCount++;
break;
}
}
}
float percentage = (userCount*100.0f)/users.length;
return percentage;
}
public boolean query3(String pageName, String pageName2){
int userCount1 = 0;
int userCount2 = 0;
String pageNumString = Integer.toString(convert(pageName));
String pageNumString2 = Integer.toString(convert(pageName2));
for(int i = 0; i < users.length; i++ )
{
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString))
{
userCount1++;
break;
}
}
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString2))
{
userCount2++;
break;
}
}
}
return userCount1 > userCount2;
}
public int query4(String pageName, int numTimes){
int userCount = 0;
String pageNumString = Integer.toString(convert(pageName));
for(int i = 0; i < users.length; i++ )//runs through each user
{ int pageCount = 0;
for(String entry : users[i].split(" "))// runs through each user's pages
{
if(entry.equals(pageNumString))
{
pageCount++; // each time page is found page count increments 1
}
} // once done running through user's pages
if(pageCount == numTimes){ // check if the number of pages is equal to the number given
userCount++; // if so increment userCount
}
}
return userCount;
}
public float query5(String pageName, String pageName2){
int viewedMore = 0;
int userCount1 = 0;
int userCount2 = 0;
String pageNumString = Integer.toString(convert(pageName));
String pageNumString2 = Integer.toString(convert(pageName2));
for(int i = 0; i < users.length; i++ )
{
for(String entry : users[i].split(" ")){
userCount1 = 0;
userCount2 = 0;
if(entry.equals(pageNumString))
{
userCount1++;
break;
}
}
for(String entry : users[i].split(" "))
{
if(entry.equals(pageNumString2))
{
userCount2++;
break;
}
}
if(userCount1 > userCount2){
viewedMore++;
}
}
return viewedMore*100.0f/users.length;
}
答案 0 :(得分:1)
至少,在query3
和query5
中,您可以为两个内部for循环中的每一个生成线程;没有理由他们必须按顺序运行。对于任何查询函数,您当然可以将数组拆分为多个部分。由于您的数据越来越大,这种方法很可能比使用主线程迭代数据更快。
我建议提供线程连续的段(例如索引0到N-1; N到N + N-1等)。之前的StackOverflow answer提供了很好的理由,说明为什么这种方法最有效。一旦你得到了一些工作,你可以使用线程数来优化。
一种方法是实现strategy pattern,这样每个查询都可以在客户端上互换,其中executeQuery()
调用是接口方法。想想让客户的电话看起来像
interface Query {
boolean executeQuery();
}
// client code...
Client client = new Client(...);
client.setQuery(new Query3(String num, String pageNum));
client.query(); // calls query.executeQuery();
在具体的Query
类中,您可以定义线程将执行的操作的各个行为。这是一个粗略的例子:
public Query3 implements Query {
Query3(String pageNum`, String pageNum2) {
this.pageNum1=pageNum1;
this.pageNum2=pageNum2;
}
boolean executeQuery() {
for(int i = 0; i < users.length; i++ ) {
SearchThread first = new SearchThread(pageNum1);
SearchThread second = new SearchThread(pageNum2);
first.run();
second.run();
}
first.join();
second.join();
return first.userCount > second.userCount;
}
SearchThread extends Thread {
String pageNumString;
int userCount;
SearchThread(String pageNumString) {
this.pageNumString=pageNumString;
}
public void run() {
// do your search over this segment of the array, adding up userCounts
}
这是另一个StackOverflow question,它描述了如何在单个阵列上运行多个线程,并使用一些样板代码。