아래 코드를 최적화하기로 결정했지만 문제가 발생했습니다. this discussion을 사용하여 ArrayList를 스레드로부터 안전한 컬렉션으로 변경하려고 시도했지만 불행히도 문제가 발생했습니다. 코드가 컴파일되지만 예외가 발생합니다. 스레드 "주요"java.lang.ClassCastException가에내 ArrayList를 Thread-Safe로 만들지 못했습니다. 스레드 "main"의 예외 java.lang.ClassCastException : 무엇이 잘못 되었습니까?
이예외 : Collections의 $ SynchronizedRandomAccessList이 bfpasswrd_multi.PasswordCracker.doItMulti (PasswordCracker.java:73)에서 인 java.util.ArrayList 캐스트 할 수없는 bfpasswrd_multi.Test.main (Test.java:16)
십시오 bfpasswrd_multi.PasswordCracker.runMulti (PasswordCracker.java:60)에서, 무엇이 잘못되었는지 말해? 사전에
package bfpasswrd_multi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class PasswordCracker
{
String passwordToCrack;
public boolean passwordFound;
int min;
int max;
StringBuffer crackedPassword;
public void prepare(String text)
{
passwordToCrack = text;
passwordFound = false;
min = 48;
max = 57; // http://ascii.cl/
crackedPassword = new StringBuffer();
crackedPassword.append((char) (min - 1));
}
public void result()
{
System.out.println("Cracked Password is: " + crackedPassword.toString());
}
public void incrementString(StringBuffer toCrack, int min, int max)
{
toCrack.setCharAt(0, (char) ((int) toCrack.charAt(0) + 1));
for (int i = 0; i < toCrack.length(); i++)
{
if (toCrack.charAt(i) > (char) max)
{
toCrack.setCharAt(i, (char) min);
if (toCrack.length() == i + 1)
{
toCrack.append((char) min);
}
else
{
toCrack.setCharAt(i + 1, (char) ((int) toCrack.charAt(i + 1) + 1));
}
}
}
}
public void runMulti(String text)
{
prepare(text);
double time = System.nanoTime();
doItMulti();
time = System.nanoTime() - time;
System.out.println(time/(1000000000));
result();
}
public void doItMulti()
{
int cores = Runtime.getRuntime().availableProcessors();
ArrayList<Future<?>> tasks ; // How do I make my ArrayList Thread-Safe? Another approach to problem in Java?
// https://stackoverflow.com/questions/2444005/how-do-i-make-my-arraylist-thread-safe-another-approach-to-problem-in-java
tasks = (ArrayList<Future<?>>) Collections.synchronizedList(new ArrayList<Future<?>>(cores));
// ArrayList<Future<?>> tasks = new ArrayList<>(cores);
ExecutorService executor = Executors.newFixedThreadPool(cores);
final long step = 2000;
for (long i = 0; i < Long.MAX_VALUE; i += step)
{
while(tasks.size() > cores)
{
for(int w = 0; w < tasks.size();w++)
{
if(tasks.get(w).isDone())
{
tasks.remove(w);
break;
}
}
try
{
Thread.sleep(0);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
{
final long j = i;
if (passwordFound == false)
{
tasks.add(executor.submit(new Runnable()
{
public void run()
{
long border = j + step;
StringBuffer toCrack = new StringBuffer(10);
toCrack.append(constructString3(j, min, max));
for (long k = j; k < border; k++)
{
incrementString(toCrack, min, max);
boolean found = toCrack.toString().equals(passwordToCrack);
if (found)
{
crackedPassword = toCrack;
passwordFound = found;
break;
}
}
}
}));
}
else
{
break;
}
}
}
executor.shutdownNow();
}
public String constructString3(long number, long min, long max)
{
StringBuffer text = new StringBuffer();
if (number > Long.MAX_VALUE - min)
{
number = Long.MAX_VALUE - min;
}
ArrayList<Long> vector = new ArrayList<Long>(10);
vector.add(min - 1 + number);
long range = max - min + 1;
boolean nextLetter = false;
for (int i = 0; i < vector.size(); i++)
{
long nextLetterCounter = 0;
while (vector.get(i) > max)
{
nextLetter = true;
long multiplicator = Math.abs(vector.get(i)/range);
if ((vector.get(i) - (multiplicator * range)) < min)
{
multiplicator -= 1;
}
vector.set(i, vector.get(i) - (multiplicator * range));
nextLetterCounter += multiplicator;
}
if (nextLetter)
{
vector.add((long) (min + nextLetterCounter - 1));
nextLetter = false;
}
text.append((char) vector.get(i).intValue());
}
return text.toString();
}
}
많은 감사합니다!
동기화 된 목록은 'ArrayList'가 아닙니다. 당신은 그 던지기를 할 수 없습니다. 'tasks '를'List> tasks;로 선언하십시오. –
나는 그 변수의 이름도 바꿀 것이다. "태스크"는 실행자 서비스에 제출하는 것이고 _future_는 다시 얻는 것입니다. 'tasks '대신'futures' 변수의 이름을 짓겠습니다. –
작동하는 것처럼 보입니다. 고마워. 오키, 나는 이름을 바꾸고 해결책을 제출한다. 당신이 말했어 고마워요. 빨리. 어쩌면 다른 최적화, 제발 말해 자유롭게. 당신의 의견은 많이 감사하겠습니다! –