我认为我对锁和基本的多线程概念有相当不错的理解,但我在这里搞错了。
所有程序应该接收文本文件的文件名和要从用户使用的线程数,然后计算该文件中“http”链接的数量,然后将该数字返回给用户。
然而,对于我的生活,我无法正确计算我的线索。我已经尝试将“count”变量设为原子整数并使用“incrementAndGet()”函数,我已经尝试将锁定放在我认为应该是的代码中,并且我已经尝试指定必要的功能是同步的,都无济于事。
我一直在做关于锁,并发等等的阅读,但我显然做了一些非常错误的事情。有人可以向我解释我在哪里/为什么需要在我的代码中放置锁(或者如何正确使用原子整数,如果这样会更有效)?
我最初使用了“count”变量时的锁定(在任何循环之外,所以它实际上做了一些事情),但是当我运行程序时,我收到各种数字。
我的代码如下所示:
import java.io.*;
import java.util.*;
import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.AtomicInteger;
public class Count
{
static String fname;
static int count = 0;
public static void main(String[] arg)
{
Scanner in = new Scanner(System.in);
int numthreads;
if( arg.length > 0 )
{
fname = arg[0];
numthreads = Integer.parseInt(arg[1]);
}
else
{
System.out.println("File?");
fname = in.nextLine();
System.out.println("Num threads?");
numthreads = in.nextInt();
}
RandomAccessFile raf;
try
{
raf = new RandomAccessFile(fname,"r");
Thread[] T = new Thread[numthreads];
for(int i=0;i<numthreads;++i)
{
T[i] = new Thread(new Task(i,numthreads,raf));
T[i].start();
}
for(Thread t : T)
{
try
{
t.join();
}
catch (InterruptedException e)
{
System.out.println("Thread join failed!");
e.printStackTrace();
System.exit(0);
}
}
System.out.println("The total is: "+count);
}
catch(IOException e)
{
System.out.println("Could not read file");
}
}
}
class Task implements Runnable
{
int myid;
int totaltasks;
RandomAccessFile raf;
ReentrantLock L = new ReentrantLock();
public Task(int myid, int totaltasks, RandomAccessFile raf)
{
this.myid=myid;
this.totaltasks=totaltasks;
this.raf = raf;
}
@Override
public void run()
{
try
{
long filesize = raf.length(); //length of the entire file
long sz = filesize / totaltasks; //length of entire file divided by number of threads gives thread size
long start = myid*sz; // thread's number * size of thread. How we find start of thread in the file
raf.seek(start);
if(start != 0 )
{
raf.readLine();
}
while(raf.getFilePointer() < (start+sz))
{
String s = raf.readLine();
Scanner sc = new Scanner(s);
while(sc.hasNext())
{
String w = sc.next();
if( w.startsWith("http://"))
{
Count.count++;
}
}
}
}
catch(IOException e)
{
System.out.println("IO error!");
}
}
}
如果在这里工作的问题比我需要在适当的位置使用锁更重要,请告诉我,我至少会有一些工作要做,但据我所知,它应该只是一个正确执行锁定的问题,我要么不了解它们如何正常工作,要么只是把它们放在所有错误的地方。