ロックと基本的なマルチスレッドの概念についてはかなり理解していたと思いますが、ここで何かをめちゃくちゃにしています。
プログラムは、テキスト ファイルのファイル名と使用するスレッドの数をユーザーから受け取り、そのファイル内の "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!");
}
}
}
適切な場所でロックを使用する必要があるよりも大きな問題がここで発生している場合は、私に知らせてください.適切にロックされていますが、それらがどのように正しく機能するかを理解していないか、間違った場所に置いているだけです。