Put class method into ThreadPoolExecutor in Java - java

I am new to Java and multithreading too. I've read about ThreadPool and saw that I can submit/execute lambda functions into ThreadPoolExecutor for example. But how can I do it for class methods in Java?
public class ParallelPointSystem{
private ArrayList<Cluster> clusters;
private ArrayList<Point> points;
private int dimension;
private int clusters_amount;
private int iterations;
private void attach_point(int i) throws Exception {
double distance = Point.get_distance(this.points.get(i), this.clusters.get(0).get_current_center());
int ind = 0;
for(int j = 1; j < clusters_amount; j++){
double dst = Point.get_distance(this.points.get(i), this.clusters.get(j).get_current_center());
if(distance > dst){
distance = dst;
ind = j;
}
}
this.clusters.get(ind).attach(this.points.get(i));
}
}
I tried to wrap a method in a class that implements the Runnable interface, but is this the only way to do that? Am I doing it right?
class Attach_Point implements Runnable{
private int i;
private ArrayList<Cluster> clusters;
private ArrayList<Point> points;
private int clusters_amount;
public Attach_Point(int i, ArrayList<Cluster> clusters, ArrayList<Point> points, int cluster_amount){
this.i = i;
this.clusters = clusters;
this.points = points;
this.clusters_amount = cluster_amount;
}
#Override
public void run(){
double distance = Point.get_distance(this.points.get(i), this.clusters.get(0).get_current_center());
int ind = 0;
for(int j = 1; j < clusters_amount; j++){
double dst = Point.get_distance(this.points.get(i), this.clusters.get(j).get_current_center());
if(distance > dst){
distance = dst;
ind = j;
}
}
try {
this.clusters.get(ind).attach(this.points.get(i));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

You don't actually need to implement Runnable. You only need to make sure to define a method on your class that matches the signature of public void run() and pass either lambda or method reference for your task.
For example this works:
class MyClass {
public void doIt() {
System.out.println("Hello "+this+" in "+Thread.currentThread());
}
}
Example calls submitting above task:
ExecutorService pool = Executors.newFixedThreadPool(1);
// Submit as method reference:
pool.execute(new MyClass()::doIt);
MyClass obj = new MyClass();
// Submit as Runnable lambda:
pool.execute(() -> obj.doIt());
Obviously if you had MyClass implements Runnable and a run() method, simply use:
pool.execute(obj);

Related

Non-deterministic behavior with Java Multithreading

I wrote a simple program that I am using to practice multithreading in Java. The goal is to test whether or not a Sudoku solution is valid: No repeating numbers in rows, columns, or sub-grids. At this point I don't care that the entries must be from 1-9. The program works fine when the Sudoku solution is invalid. When the Sudoku solution is valid (on the same input), the program works only sometimes. Specifically, "win" may or may not be printed.
My program works by creating RowThread, ColumnThread, and GridThread. Each are of them check whether the solution has valid rows, columns and grids, respectively. When a thread is finished checking, it calls the appropriate setter method in SudokuTest, which will call the end method in Main if the solution is invalid. If the thread does not determine that the solution is invalid, the setter method will record that the row, column, or grid has been checked, and then call the allChecked method. allChecked checks if row, column, and grid have been checked. If so, then the solution is valid, so it calls Main.success(), which should print "win." Here is my Main class:
public class Main{
public static void end(){//called by SudokuTest when the solution is invalid
System.out.println("fail");
System.exit(0);
}
public static void success() {//called by SudokuTest when the solution is valid
System.out.println("win");/*this line will not always print,
but it is reached in the debugger when I set a breakpoint.*/
System.exit(0);
}
public static void main(String[] args) {
int[][] sudokuSolution = new int[9][9];
int k = 0;
for (int i = 0; i < 9; i++) { //loop fills up a 2d array with the numbers 0-80, a valid solution
for (int j = 0; j < 9; j++) {
sudokuSolution[i][j] = k;
k++;
}
}
//sudokuSolution[1][1] = 0;//Testing an invalid solution
SudokuTest t = new SudokuTest();//
Runnable r = new RowThread(sudokuSolution, t);
Runnable c = new ColumnThread(sudokuSolution, t);
Runnable g = new GridThread(sudokuSolution, t);
new Thread(r).start();
new Thread(c).start();
new Thread(g).start();
}
}
My RowThread class:
public class RowThread implements Runnable {
int[][] _sudoku;
SudokuTest _t;
public RowThread(int[][] sudoku, SudokuTest t) {
_sudoku = sudoku;
_t = t;
}
private void isFail() { //issue: how to get this info back to my Main function?
for(int i = 0; i < _sudoku.length; i++) {
for(int j = 0; j< _sudoku.length; j++) {
for (int k = j+1; k< _sudoku.length; k++) {
if (_sudoku[i][j] == _sudoku[i][k]) {
_t.setRow(true);
return;
}
}
}
}
_t.setRow(false);
}
#Override
public void run() {
isFail();
}
}
My ColumnThread and GridThread classes are the same as RowThread, except for the logic in the isFail() method.
My SudokuTest class:
public class SudokuTest {
public boolean _rowBad;
public boolean _colBad;
public boolean _gridBad;
public boolean _rowChecked;
public boolean _colChecked;
public boolean _gridChecked;
public SudokuTest(){
}
public void setRow(boolean b) {
_rowBad = b;
_rowChecked = true;
if (b) {
Main.end();
}
}
public void setCol(boolean b) {
_colBad = b;
_colChecked = true;
if (b) {
Main.end();
}
}
public void setGrid(boolean b) {
_gridBad = b;
_gridChecked = true;
if (b) {
Main.end();
}
allChecked();
}
public void allChecked() {
if (_gridChecked && _colChecked && _rowChecked) {
Main.success();
}
}
}
Answer: as Maarten Bodewes pointed out, my mistake was to not call allChecked in setCol and setRow.

why parallelizing the code of this implementation's genetic algorithm for the resolution of the tsp is much slower?

I am working on a university project on genetic algorithms to solve the TSP Problem and the teacher asked us to parallelize the optimize function. I tried to implement the optimize function in parallel and it works but it is much slower.
Tips?
You can find the original code here: https://github.com/Mentathiel/StackAbuseGeneticTravelingSalesman
public SalesmanGenome optimizeP() throws InterruptedException {
//Setting all the constant attributes that will not change during the optimizations
addInP.setGenerationSize(generationSize);
addInP.setGenomeSize(genomeSize);
addInP.setMutationRate(mutationRate);
addInP.setNumberOfCities(numberOfCities);
addInP.setStartingCity(startingCity);
addInP.setTravelPrices(travelPrices);
addInP myThreads[]= new addInP[N_THREADS];
List<SalesmanGenome> population = initialPopulation();//RandomPopulation
SalesmanGenome globalBestGenome = population.get(0);
for (int i = 0; i < maxIterations; i++) {
addInP.setPopulation(selection(population));
addInP.setCurrentGenerationSize(0);
addInP.setGeneration(new ArrayList<>());
for (int j = 0; j < N_THREADS; j++) {
myThreads[j]= new addInP();
myThreads[j].start();
myThreads[j].join();
}
population = addInP.getGeneration();//population generated each step
addInP.setCurrentGenerationSize(0); //Resetting current Generation Size
globalBestGenome = Collections.min(population);
if (globalBestGenome.getFitness() < targetFitness)
break;
}
return globalBestGenome;
}
This is the run function of my addInP class that extends thread
public void run()
{
while( getCurrentGenerationSize() < generationSize){
List<SalesmanGenome> parents = pickNRandomElements(population,2);
List<SalesmanGenome> children = crossover(parents);
children.set(0, mutate(children.get(0)));
children.set(1, mutate(children.get(1)));
generation.addAll(children);
setCurrentGenerationSize( getCurrentGenerationSize()+2);
}
}
These are the attributes of my addInP class and the methods to use the shared variable currentGenerationSize
private static List<SalesmanGenome> population;
private static volatile int currentGenerationSize ;
private static int generationSize;
private static int[][] travelPrices;
private static int startingCity;
private static int numberOfCities;
private static int genomeSize;
private static float mutationRate;
private static List<SalesmanGenome> generation;
public synchronized int getCurrentGenerationSize() {
return currentGenerationSize;
}
public synchronized static void setCurrentGenerationSize(int currentGenerationSize) {
addInP.currentGenerationSize = currentGenerationSize;
}

Problems with Static Internal Threads When Accessing Static Variables in External Classes

This problem has puzzled me for a long time, please help me,thanks.
This is my java code.
package com.concurrent.example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* P683
*/
class CircularSet {
private int[] array;
private int len;
private int index = 0;
public CircularSet (int size) {
array = new int[size];
len = size;
for (int i = 0; i < size; i++) {
array[i] = -1;
}
}
public synchronized void add(int i ) {
array[index] = i;
index = ++index % len;
}
public synchronized boolean contains(int val) {
for (int i = 0; i < len; i++) {
if(array[i] == val) {
return true;
}
}
return false;
}
}
public class SerialNumberChecker {
private static final int SIZE = 10;
private static CircularSet serials = new CircularSet(1000);
private static ExecutorService exec = Executors.newCachedThreadPool();
private static int serial;
static class SerialChecker implements Runnable {
#Override
public void run() {
while(true) {
//int serial;
synchronized (serials) {
serial = SerialNumberGenerator.nextSerialNumber();
}
if (serials.contains(serial)) {
System.out.println("Duplicate: " + serial);
System.exit(0);
}
System.out.println(serial);
serials.add(serial);
}
}
}
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < SIZE; i++) {
exec.execute(new SerialChecker());
if (args.length > 0) {
TimeUnit.SECONDS.sleep(new Integer(args[0]));
System.out.println("No duplicates detected");
System.exit(0);
}
}
}
}
It can stop, but when i uncomment //int serial;The result is different,it can't stop.Why does this temporary variable have a different result than the static variable of the external class. Is this the reason of using a thread?
The code of SerialNumberGenerator:
public class SerialNumberGenerator {
private static volatile int serialNumber = 0;
public static int nextSerialNumber() {
return serialNumber ++; //Not thread-safe
}
}
With private static int serial, all SerialNumberCheckers share the same serial. For example:
Thread1 set serial = 1
Thread2 set serial = 2
Thread1 put 2 into CircularSet.
Thread2 found it duplicate and exit.
However, if you declare another int serial in the run method, It will shadow the private static int serial, which means all threads has its own serial and they will assign & check it. Since the generation of serial is in the synchronized block, there will be no duplicates.

Sequential thread execution using wait/notify

Now I'm struggling with the task from the title. I create X threads, each of them prints Y equal digits (getting from constructor, for example "11111", "222222" etc) for Z times in cycle. So the result looks like:
111111111
222222222
333333333
111111111
222222222
333333333
for X = 3, Y = 9 and Z = 2.
Firstly I've solved this issue using sleep, interrupt and passing "next" thread to the constructor of previous one. One interrupts another etc. Next step is to get the same output using wait/notify instead sleep and interrupt. As far as I can see, it's neccesary to create the shared monitor object, to invoke wait after every printing and in a some moment " I should invoke notifyAll.
Current code is:
public class PrinterController {
private static final int THREADS_NUMBER = 5;
public static void main(String[] args) {
Printer[] printers = new Printer[THREADS_NUMBER];
for (int i = 0; i < THREADS_NUMBER; i++) {
printers[i] = new Printer(i);
printers[i].start();
}
}
}
public class Printer extends Thread {
private static int portion = 10;
private static int totalNumber = 100;
private int digit;
private static final Object monitor = new Object();
public Printer(int digit) {
this.digit = digit;
}
#Override
public void run() {
synchronized (monitor) {
int portionsNumber = totalNumber / portion;
for (int i = 0; i < portionsNumber; i++) {
printLine();
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void printLine() {
for (int j = 0; j < portion; j++) {
System.out.print(digit);
}
System.out.println();
}
}
Could you help to improve it? I found similar tasks but they don't contain appropriate answers. Thanks.
Final solution based on the Nadir's answer:
public class Printer extends Thread {
private static int portion = 10;
private static int totalNumber = 100;
private int digit;
static Object monitor = new Object();
static Integer counter = 0;
public Printer(int digit) {
this.digit = digit;
}
#Override
public void run() {
int portionsNumber = totalNumber / portion;
for (int i = 0; i < portionsNumber; i++) {
synchronized (monitor) {
while (digit != counter) {
try {
monitor.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
printLine();
monitor.notifyAll();
}
}
}
private void printLine() {
for (int j = 0; j < portion; j++) {
System.out.print(digit);
}
System.out.println();
counter = (counter + 1) % PrinterController.THREADS_NUMBER;
}
}
It can be accomplished with a class used to synchronize the threads (and even make sure they are orderer). All threads would share the same instance.
public class Synchronizer
{
private int nextThread;
private int maxNumThreads;
public Synchronizer(int numThreads)
{
maxNumThreads = numThreads;
nextThread = 0;
}
public void doSync(int threadId) throws Exception
{
synchronized(this)
{
while(nextThread != threadId)
{
wait();
}
}
}
public void threadDone(int threadId) throws Exception
{
synchronized(this)
{
nextThread = (threadId + 1) % maxNumThreads;
notifyAll();
}
}
}
On your thread's run(), you would call doSync() before printing anything. Then you would put the code for printing, and afterwards, you would call threadDone(), allowing the next thread to be released. The id is used to enforce an order.

Java - Multithreads immutable object

I have this class:
class S2Es2SharedState {
public int x;
public int y;
}
that is used to share an s2Es2SharedState object in every thread inside in the loop:
class S2Es2Worker implements Runnable {
private final int id;
private S2Es2SharedState state;
private final int delay;
private int numErrors = 0;
public S2Es2Worker(final int id, final S2Es2SharedState state,
final int delay) {
this.state = state;
this.delay = delay;
this.id = id;
this.numErrors = 0;
System.out.println("Worker " + id + ": created with " + delay
+ " ms delay");
}
#Override
public void run() {
boolean check = true;
System.out.println("Worker " + id + ": started");
for (int i = 0; i < 150; i++) {
state.x++;
try {
Thread.sleep(delay);
} catch (final InterruptedException e) {
// do nothing
}
state.y++;
}
}
}
in this program working 10 threads where each of them enter in the loop and increment 150 times the value of x and y of the shared object, so the final result in the x and y of the shared object is 1500.If i don't change anything this program have a problem of race condition, so for fix this problem i used the lock (and it works). But now i want to fix the problem of the race condition using the immutable object instead of the locks. so i changed the class of the shared object in this way:
final class S2Es2SharedState {
private final int x;
private final int y;
public S2Es2SharedState(final int x, final int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public S2Es2SharedState incrementX() {
return new S2Es2SharedState(x+1, y);
}
public S2Es2SharedState incrementY() {
return new S2Es2SharedState(x, y+1);
}
}
and in the run() method i changed the state variable in this way:
class S2Es2Worker implements Runnable {
....
private volatile S2Es2SharedState state;
....
and in the for loop i did this edit:
for (int i = 0; i < 150; i++) {
state = state.incrementX();
try {
Thread.sleep(delay);
} catch (final InterruptedException e) {
// do nothing
}
state = state.incrementY();
}
}
But i don't know why the final result is that the shared object has instead of x=1500 and y=1500 150 in both variableHow can i fix the problem with the race of condition using the immutable object?
I'm going to assume you create a S2Es2SharedState (use simpler names for asking questions) as
S2Es2SharedState state = new S2Es2SharedState(0, 0)
and passing it to the S2Es2Worker instances something like
for (int i = 0; i < 10;i++) {
S2Es2Worker worker = new S2Es2Worker(i, state, 5);
new Thread(worker).start();
}
In java, everything is passed by value. So the using state as a method argument, a copy of the value of the reference is passed.
So the field
private volatile S2Es2SharedState state;
is also referencing the same object. However, if you change the reference that the field state is holding, for example with
state = state.incrementX();
that doesn't affect any other references.

Categories

Resources