I'm studying about parallel programming and testing this brute force code, to crack a password with 7 positions without and with parallelism, but when applying parallel programming, the code is running slower than before. Does anyone know why? How can I use parallel programming in this code to make it faster? thanks.
public class Worker extends Thread{
private static final int[] valuesCaracter = {48, 48, 48, 48, 48, 48, 48};
private static final int arraySize = valuesCaracter.length;
private static char[] symbols = new char[arraySize];
private static String password = null;
#Override
public void run() {
generatePasswordCaracters();
}
public static int ajustaValor(int valueASCII) {
return switch (valueASCII) {
case 58 -> 65;
case 91 -> 97;
default -> valueASCII;
};
}
public static String generatePasswordCaracters() {
for (int i = 0; i < arraySize; i++) {
while (valuesCaracter[i] <= 122) {
for (int j = 0; j < symbols.length; j++) {
symbols[j] = (char) valuesCaracter[j];
}
password = new String(symbols);
System.out.println(password);
valuesCaracter[6]++;
for(int k = arraySize - 1; k >= 1; k--) {
if (valuesCaracter[k] > 122) {
valuesCaracter[k - 1]++;
valuesCaracter[k] = 48;
} else {
valuesCaracter[k] = ajustaValor(valuesCaracter[k]);
}
}
}
}
return password;
}
}
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.FileHeader;
import java.io.File;
import java.util.List;
public class App {
public static void main(String[] args) {
Worker[] Workers =
{new Worker(),
new Worker(),
new Worker(),
new Worker(),
new Worker(),
new Worker()};
for (Worker workerStart : Workers) {
workerStart.start();
}
try {
for (Worker workerJoin : Workers) {
workerJoin.join();
}
}catch (InterruptedException e) {
System.out.println(e.getMessage());
}
try {
ZipFile zipFile = new ZipFile(new File("C:\\vsCodeProjects-Java\\BruteForce\\src\\file.zip"));
if (zipFile.isEncrypted()) {
zipFile.setPassword(Worker.generatePasswordCaracters().toCharArray());
}
List<FileHeader> fileHeaderList = zipFile.getFileHeaders();
for (FileHeader o : fileHeaderList) {
zipFile.extractFile(o, "C:\\vsCodeProjects-Java\\BruteForce\\src");
System.out.println("This is the password");
}
} catch (Exception e) {
System.out.println("Wrong password");
}
}
}
This "parallel" code is being executed sequentially.
Main thread blocked at each step of iteration, wait for every worker to do its job. Javadoc says join():
Waits for this thread to die.
So actually although this you've created multiple threads your code will be even slower than sequential execution because threads are not cheap.
Choose either: don't control the execution of your threads, or perform these tasks in a single thread.
Sidenote: implementing Runnable is more flexible than extending Thread. Because you can start a thread only once, but the same runnable task could be reused as many times as needed.
And if your goal to parallelize a single task, you might take a look at ForkJoin framework, which will allow splitting the task in to multiple. For that Worker class should extend either RecursiveTask or RecursiveAction and override method compute().
Related
My first question, Thank for your help!
I'm trying to print odd and even numbers 1~100 alternatively using two threads.
Expected results:
pool-1-thread-1=> 1
pool-1-thread-2=> 2
pool-1-thread-1=> 3
pool-1-thread-2=> 4
......
pool-1-thread-1=> 99
pool-1-thread-2=> 100
I think i can use FairSync, but it can only guarantee that most of the print is correct. like this:
pool-1-thread-1=> 55
pool-1-thread-2=> 56
pool-1-thread-1=> 57
pool-1-thread-2=> 58
pool-1-thread-2=> 59 //※error print※
pool-1-thread-1=> 60
pool-1-thread-2=> 61
pool-1-thread-1=> 62
I don't know why is the order lost in very few cases?
You can criticize my code and my English.
Here is my code:
private static final int COUNT = 100;
private static final int THREAD_COUNT = 2;
private static int curr = 1;
static ReentrantLock lock = new ReentrantLock(true);
static ExecutorService executorService = Executors.newCachedThreadPool();
public static void main(String[] args) {
Runnable task = () -> {
for (; ; ) {
try {
lock.lock();
if (curr <= COUNT) {
System.out.println(Thread.currentThread().getName() + "=> " + curr++);
} else {
System.exit(0);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
for (int i = 0; i < THREAD_COUNT; i++) {
executorService.execute(task);
}
}
No dear your implementation is not correct. Which thread get's the opportunity to RUN is decided by the OS. Thread 1 & 2 will execute one after another cannot be guaranteed.
You can fix your code by checking the previous value of the variable curr and if the value is not what this thread expects don't increment and print.
for eg :
if(curr.threadName.equals("Thread 2") && (curr%2 !=0))
{
// Print
// Increment
}
You cant use single lock to achieve this. Even ReentrantLock gives fairness but it cant control thread schedule.
We can achieve throw inter thread communication like Semaphore. Semaphore controls the thread execution.
We create two threads, an odd thread, and an even thread. The odd thread would print the odd numbers starting from 1, and the even thread will print the even numbers starting from 2.
Create two semaphores, semOdd and semEven which will have 1 and 0 permits to start with. This will ensure that odd number gets printed first.
class SharedPrinter {
private Semaphore semEven = new Semaphore(0);
private Semaphore semOdd = new Semaphore(1);
void printEvenNum(int num) {
try {
semEven.acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + num);
semOdd.release();
}
void printOddNum(int num) {
try {
semOdd.acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println(Thread.currentThread().getName() + num);
semEven.release();
}
}
class Even implements Runnable {
private SharedPrinter sp;
private int max;
// standard constructor
#Override
public void run() {
for (int i = 2; i <= max; i = i + 2) {
sp.printEvenNum(i);
}
}
}
class Odd implements Runnable {
private SharedPrinter sp;
private int max;
// standard constructors
#Override
public void run() {
for (int i = 1; i <= max; i = i + 2) {
sp.printOddNum(i);
}
}
}
public static void main(String[] args) {
SharedPrinter sp = new SharedPrinter();
Thread odd = new Thread(new Odd(sp, 10),"Odd");
Thread even = new Thread(new Even(sp, 10),"Even");
odd.start();
even.start();
}
Refer : here
I'd like to keep a counter of executed threads, to use in the same threads that I am executing.
The problem here is that although the counter increases, it increases unevenly and from the console output I got this (I have a for loop that executes 5 threads with ExecutorService):
This is a test. N:3
This is a test. N:4
This is a test. N:4
This is a test. N:4
This is a test. N:4
As you can see instead of getting 1,2,3,4,5 I got 3,4,4,4,4.
I assume this is because the for loop is running fast enough to execute the threads, and the threads are fast enough to execute the code requesting for the counter faster than the counter can update itself (does that even make sense?).
Here is the code (it is smaller and there is no meaningful use for the counter):
for (int i = 0; i < 5; i++)
{
Thread thread;
thread = new Thread()
{
public void run()
{
System.out.println("This is test. N: "+aldo );
//In here there is much more stuff, saying it because it might slow down the execution (if that is the culprit?)
return;
}
};
threadList.add(thread);
}
//later
for (int i = 0; i < threadList.size(); i++)
{
executor.execute(threadList.get(i));
aldo = aldo + 1;
}
executor.shutdown();
try
{
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
catch (InterruptedException e)
{
}
Yes, aldo the counter ( with a few other lists, I think) are missing from the code (they are very simple).
The best way I know of doing this is by creating a custom thread class with a constructor that passes in a number. The variable holding the number can then be used later for any needed logging. Here is the code I came up with.
public static void main(String[] args) {
class NumberedThread implements Runnable {
private final int number;
public NumberedThread(int number) {
this.number = number;
}
#Override
public void run() {
System.out.println("This is test. N: " + number);
}
}
List<Thread> threadList = new ArrayList<>();
for (int i = 1; i < 6; i++) threadList.add(new Thread(new NumberedThread(i)));
ExecutorService executor = Executors.newFixedThreadPool(10);;
for (Thread thread : threadList) executor.execute(thread);
executor.shutdown();
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
catch (InterruptedException ignored) { }
}
You could also use a string object instead if you wanted to name the threads.
aldo is not modified by the tasks in the thread, but instead is modified in the main thread, here:
for (int i = 0; i < threadList.size(); i++) {
executor.execute(threadList.get(i));
//here...
aldo = aldo + 1;
}
Also, since you want a counter that can increase its value in several threads, then you may use an AtomicInteger rather than int.
Your code should look like this:
AtomicInteger aldo = new AtomicInteger(1);
for (int i = 0; i < 5; i++) {
executor.execute( () -> {
System.out.println("This is test. N: " + aldo.getAndIncrement());
});
}
I'm trying to implement a concurrent cache in java for learning propose.
This code is responsable for garantee thread-safy operations. So, whenever a thread try to fetch a value, if this value is not already cached, the algorithm should calculate it from the last cached one.
My problem is that i'm getting null values that are supposed to be already cached. I'm using semaphore (though i've tried with ReentrantLock too, so i think it's not the problem) to assure the thread-safety access to an HashMap.
Note that i would like to restrict the locked area to the smallest possible. So i would not like to synchronize the entire method or utilize an already thread safe ConcurrentMap.
Here is a complete simple code:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Semaphore;
public class ConcurrentCache {
private final Semaphore semaphore = new Semaphore(1);
private final Map<Integer, Integer> cache;
private int lastCachedNumber;
public ConcurrentCache() {
cache = new HashMap<Integer, Integer>();
cache.put(0, 0);
lastCachedNumber = 0;
}
public Integer fetchAndCache(int n) {
//if it's already cached, supposedly i can access it in an unlocked way
if (n <= lastCachedNumber)
return cache.get(n);
lock();
Integer number;
if (n < lastCachedNumber) { // check it again. it may be updated by another thread
number = cache.get(n);
} else {
//fetch a previous calculated number.
number = cache.get(lastCachedNumber);
if (number == null)
throw new IllegalStateException(String.format(
"this should be cached. n=%d, lastCachedNumber=%d", n,
lastCachedNumber));
for (int i = lastCachedNumber + 1; i <= n; i++) {
number = number + 1;
cache.put(i, number);
lastCachedNumber = i;
}
}
unlock();
return number;
}
private void lock() {
try {
semaphore.acquire();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
private void unlock() {
semaphore.release();
}
public static void main(String[] args) {
ConcurrentCache cachedObject = new ConcurrentCache();
for (int nThreads = 0; nThreads < 5; nThreads++) {
new Thread(new Runnable() {
#Override
public void run() {
for (int cacheValue = 0; cacheValue < 1000; cacheValue++) {
if (cachedObject.fetchAndCache(cacheValue) == null) {
throw new IllegalStateException(String.format(
"the number %d should be cached",
cacheValue));
}
}
}
}).start();
}
}
}
Thank you for you help.
Few pointers/ideas:
1) pre-size your Map when you create it to accommodate all/many of your future cached values, Map resizing is very thread unsafe and time consuming
2) you can simplify your whole algorithm to
YourClass.get(int i) {
if (!entryExists(i)) {
lockEntry(i);
entry = createEntry(i);
putEntryInCache(i, entry);
unlockEntry(i);
}
return entry;
}
Edit
Another point:
3) your approach to caching is very bad - imagine what will happen if the 1st request is to get something # position 1,000,000?
Pre-populate in separate thread is going to be a lot better...
Problem description:
We have a given matrix randomly filled with digits and have to create separate threads for each row of the matrix that count how many times the digits encounter in that row.
Without these sleeps in the main thread, it's not working correctly..
Here's my solution.
Also it's following here:
public class TestingMatrixThreads {
public static void main(String[] arr) throws InterruptedException {
int[][] a = new int[67][6];
// class.Count works with class.Matrix, that's why I've made it this way
Matrix m = new Matrix(a);
m.start();
Thread.sleep(1000); // Here comes the BIG question -> how to avoid these
// manually created pauses
Count c;
Thread t;
// Creating new threads for each row of the matrix
for (int i = 0; i < Matrix.matr.length; i++) {
c = new Count(i);
t = new Thread(c);
t.start();
}
//Again - the same question
System.out.println("Main - Sleep!");
Thread.sleep(50);
System.out.println("\t\t\t\t\tMain - Alive!");
int sum = 0;
for (int i = 0; i < Count.encounters.length; i++) {
System.out.println(i + "->" + Count.encounters[i]);
sum += Count.encounters[i];
}
System.out.println("Total numbers of digits: " + sum);
}
}
class Count implements Runnable {
int row;
public static int[] encounters = new int[10]; // here I store the number of each digit's(array's index) encounters
public Count(int row) {
this.row = row;
}
public synchronized static void increment(int number) {
encounters[number]++;
}
#Override
public void run() {
System.out.println(Thread.currentThread().getName() + ", searching in row " + row + " STARTED");
for (int col = 0; col < Matrix.matr[0].length; col++) {
increment(Matrix.matr[row][col]);
}
try {
Thread.sleep(1); // If it's missing threads are starting and stopping consequently
} catch (InterruptedException e) {
}
System.out.println(Thread.currentThread().getName() + " stopped!");
}
}
class Matrix extends Thread {
static int[][] matr;
public Matrix(int[][] matr) {
Matrix.matr = matr;
}
#Override
public void run() {
//print();
fill();
System.out.println("matrix filled");
print();
}
public static void fill() {
for (int i = 0; i < matr.length; i++) {
for (int j = 0; j < matr[0].length; j++) {
matr[i][j] = (int) (Math.random() * 10);
}
}
}
public static void print() {
for (int i = 0; i < matr.length; i++) {
for (int j = 0; j < matr[0].length; j++) {
System.out.print(matr[i][j] + " ");
}
System.out.println();
}
}
}
P.S. I'm sorry if this question is too stupid for you to answer, but I'm a newbie in Java programming, as well as it's my very first post in stackoverflow, so please excuse me for the bad formatting, too :)
Thank you in advance!
Change the Thread.sleep by m.join()
Doing this will make the main thread wait for the other to complete its work and then it will continu its execution.
Cheers
To answer your main question:
Thread.join();
For example:
public static void main(String[] args) throws Exception {
final Thread t = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Do stuff");
}
});
t.start();
t.join();
}
The start call, as you know, kicks off the other Thread and runs the Runnable. The join call then waits for that started thread to finish.
A more advanced way to deal with multiple threads is with an ExecutorService. This detaches the threads themselves from the tasks they do. You can have a pool of n threads and m > n tasks.
Example:
public static void main(String[] args) throws Exception {
final class PrintMe implements Callable<Void> {
final String toPrint;
public PrintMe(final String toPrint) {
this.toPrint = toPrint;
}
#Override
public Void call() throws Exception {
System.out.println(toPrint);
return null;
}
}
final List<Callable<Void>> callables = new LinkedList<>();
for (int i = 0; i < 10; ++i) {
callables.add(new PrintMe("I am " + i));
}
final ExecutorService es = Executors.newFixedThreadPool(4);
es.invokeAll(callables);
es.shutdown();
es.awaitTermination(1, TimeUnit.DAYS);
}
Here we have 4 threads and 10 tasks.
If you go down this route you probably need to look into the Future API to so that you can check whether the tasks completed successfully. You can also return a value from the task; in your case a Callable<Integer> would seem to be appropriate so that you can return the result of your calculation from the call method and gather up the results from the Future.
As other Answers have stated, you can do this simply using join; e.g.
Matrix m = new Matrix(a);
m.start();
m.join();
However, I just want to note that if you do that, you are not going to get any parallelism from the Matrix thread. You would be better of doing this:
Matrix m = new Matrix(a);
m.run();
i.e. executing the run() method on the main thread. You might get some parallelism by passing m to each "counter" thread, and having them all join the Matrix thread ... but I doubt that it will be worthwhile.
Frankly, I'd be surprised if you get a worthwhile speedup for any of the multi-threading you are trying here:
If the matrix is small, the overheads of creating the threads will dominate.
If the matrix is large, you are liable to run into memory contention issues.
The initialization phase takes O(N^2) computations compared with the parallelized 2nd phase that has N threads doing O(N) computations. Even if you can get a decent speedup in the 2nd phase, the 1st phase is likely to dominate.
I have a problem with Threads in Java.
I would like to write a program where there is Class Main which has ArrayList of Threads of some class (Class Task) which just writes a letter and the number. Object Main just wakes one Thread from ArrayList and let it to do something while the same object(Main) sleeps another one.
But there is one problem even if I change the Main.ACTIVE to false it does not end all of the Threads some stay on, and it's random, I just would like to make them end and write:
I am saying goodbay + character - sth like that
public class Main extends Thread {
ArrayList<Thread> threads;
static boolean ACTIVE = true;
public Main() {
super();
threads = new ArrayList<Thread>();
}
public void run(){
Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
threads.get(i).start();
}
System.out.println("BEFORE synchronized(monitor)");
synchronized(monitor){
while (System.currentTimeMillis() - cT < 1000) {
try{
monitor.notify();
Thread.sleep(50);
monitor.wait();
} catch(Exception e){
e.printStackTrace();}
}
System.out.println("BEFORE ACTIVE= FALSE and after WHILE in Main");
ACTIVE = false;
for(int i = 0; i < threads.size(); i++){
System.out.println(threads.get(i).getState());
}
}
System.out.println("LAST COMMAND IN MAIN");
}
}
public static void main(String[] args) {
new Main().start();
//new Thread(new Task(65)).start();
}
}
And the Task Class
public class Task implements Runnable {
int nr;
char character;
Object monitor;
public Task(int literaASCII, Object monitor) {
this.nr = 0;
this.monitor = monitor;
character = (char) (literaASCII);
}
#Override
public void run() {
synchronized (monitor) {
while (Main.ACTIVE) {
try {
System.out.println("ENTERING WHILE IN TASK");
monitor.wait();
System.out.print(nr + "" + character + ", ");
nr++;
int r = (int) ((Math.random() * 50) + 50); // <500ms,1000ms)
Thread.sleep(r);
} catch (Exception e) {e.printStackTrace();}
monitor.notify();
System.out.println("YYYYYYYYY");
}
System.out.println("AFTER WHILE IN Task");
}
System.out.println("I am saying goodbye " + character);
}
}
I would recommend that you look at the more modern concurrency classes in java.util.concurrent package, especially ExecutorService. And read "Java Concurrency In Practice."
Your problem is for starters that ACTIVE should be marked as volatile. Any variable that is shared by multiple threads needs to somehow be synchronized or marked as volatile so that it will have a memory barrier around its reading and writing.
Another thing you can do from a boolean standpoint is to use the AtomicBoolean class instead of a volatile boolean.
Instead of a static volatile boolean, you might instead consider to have a volatile boolean for each Task object so that Main has more fine grained control over the individual tasks and you are using a static "global" variable. You could even add a task.shutdown() method to set the active flag.
Lastly, as #duffmo mentioned, you should always consider using one of the thread-pools ExecutorService if you always just want to have one thread running. Something like Executors.newFixedThreadPool(1). But I can't quite tell if you only want one thread all of the time. If you used an ExecutorService then main would just do:
ExecutorService threadPool = Executors.newFixedThreadPool(1);
List<Future> futures = new ArrayList<Future>();
for (int i = 0; i <= 5; i++) {
// the monitor would not be needed
threadPool.submit(new Task(i + 65));
}
threadPool.shutdown();
for (Future future : futures) {
// this waits for the working task to finish
future.get();
}
But if you need your background task to stop and start like it is currently doing with the monitor then this model might not work.
Now naswer is
0A, 0B, 0C, 0D, 0E, 0F, 1A, 1B, 1C, 1D, 1E, 1F, WAITING
WAITING
WAITING
WAITING
WAITING
WAITING
LAST COMMAND IN MAIN
I added sleep after starting threads
import java.util.ArrayList;
public class Main extends Thread {
ArrayList<Thread> threads;
volatile static boolean ACTIVE = true;
public Main() {
super();
threads = new ArrayList<Thread>();
}
public void run(){
Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
threads.get(i).start();
}
try{Thread.sleep(50);}catch(Exception e){e.printStackTrace();}
// System.out.println("BEFORE synchronized(monitor)");
synchronized(monitor){
while (System.currentTimeMillis() - cT < 1000) {
try{
monitor.notify();
Thread.sleep(500);
monitor.wait();}catch(Exception e){e.printStackTrace();}
}
// System.out.println("BEFORE ACTIVE= FALSE and after WHILE in Main");
ACTIVE = false;
for(int i = 0; i < threads.size(); i++){
System.out.println(threads.get(i).getState());
}
}
System.out.println("LAST COMMAND IN MAIN");
}
public static void main(String[] args) {
new Main().start();
//new Thread(new Task(65)).start();
}
}
and the TASK
public class Task implements Runnable {
int nr;
char character;
Object monitor;
public Task(int literaASCII, Object monitor) {
this.nr = 0;
this.monitor = monitor;
character = (char) (literaASCII);
}
#Override
public void run() {
synchronized (monitor) {
while (Main.ACTIVE) {
try {
// System.out.println("ENTERING WHILE IN TASK");
monitor.wait();
System.out.print(nr + "" + character + ", ");
nr++;
int r = (int) ((Math.random() * 50) + 50); // <500ms,1000ms)
Thread.sleep(r);
} catch (Exception e) {e.printStackTrace();}
monitor.notify();
// System.out.println("YYYYYYYYY");
}
System.out.println("AFTER WHILE IN Task");
}
System.out.println("I am saying goodbye " + character);
}
}