Ich entschied mich, das untenstehende Codeelement zu optimieren, stieß aber auf Probleme. Ich habe versucht, die ArrayList in thread-sichere Sammlung zu ändern, indem Sie this discussion verwenden, aber leider ging etwas schief. Der Code kompiliert, aber löst die Ausnahme aus. Fehler beim Erstellen meiner ArrayList Thread-Safe. Ausnahme im Thread "main" java.lang.ClassCastException: Was ist falsch?
Exception in thread "main" java.lang.ClassCastException: java.util.Collections $ SynchronizedRandomAccessList kann nicht auf java.util.ArrayList bei bfpasswrd_multi.PasswordCracker.doItMulti (PasswordCracker.java:73) gegossen werden bei bfpasswrd_multi.PasswordCracker.runMulti (PasswordCracker.java:60) bei bfpasswrd_multi.Test.main (Test.java:16)
Bitte, sagen Sie mir, was ist falsch?
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();
}
}
Vielen Dank im Voraus!
Eine synchronisierte Liste ist keine 'ArrayList'. Du kannst diesen Cast nicht machen. Deklarieren Sie "Aufgaben" als "Liste> Aufgaben;" stattdessen. –
Ich würde auch den Namen dieser Variablen ändern. Eine "Aufgabe" ist, was Sie an den Executor-Service senden, eine _Future_ ist, was Sie zurückbekommen. Ich würde die Variable "Futures" anstelle von "Aufgaben" nennen. –
Scheint wie es funktioniert. Danke. Okey, ich ändere die Namen und reiche die Lösung ein. Danke, dass Sie es erwähnen. schnellstmöglich. Vielleicht eine andere Optimierung, bitte zögern Sie nicht mir zu sagen. Ihre Meinung wird sehr geschätzt! –