Non-deterministic behavior with Java Multithreading - java

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.

Related

Multi threading issue

I need to initialize an Array of n Threads. Each Thread represents a number which randomly initialized in the Thread's Object creation.
The program should run m iterations. On each iteration, the Threads number needs to be updated. If both left and right neighbors in the Array are bigger than this Thread then the Thread's value will get +1 in the next iteration. If both neighbors values are lower then the Thread's value then the Thread's value will get -1. Otherwise, the Thread's value will not change.
The code starts from a code line in a GUI class. The line is:
Controller cont = new Controller(n,m)
The code enters updated method in class Controller just once and then all the Threads are going to sleep without implementing updated method.
Why is that?
This is my code:
public class Threads extends Thread
{
private int num;
private Controller cont;
private int toUpdate;
private int index;
public Threads(Controller c, int i)
{
num = (int)(Math.random() * 100 + 1); // random number between 1-100
cont = c;
index = i;
}
public void run()
{
for(int j = 1; j <= cont.getIterations(); j++)
{
toUpdate = cont.checkValue(this, this.getIndex());
cont.finished();
cont.threadWait();
num += toUpdate;
cont.updated();
cont.threadWait();
}
}
public int getValue()
{
return this.num;
}
public int getIndex()
{
return this.index;
}
}
public class Controller
{
private Threads[] threadsArray;
private int iterations;
private boolean finished = false;
private static int numOfThreads;
public Controller(int n, int m)
{
threadsArray = new Threads[n];
for(int i=0; i < threadsArray.length; i++)
threadsArray[i] = new Threads(this, i);
iterations = m;
numOfThreads = n;
printResults();
for(int i=0; i < threadsArray.length; i++)
threadsArray[i].start();
}
public synchronized void threadWait()
{
while(!finished)
{
try{ wait(); }
catch(InterruptedException e) {}
}
numOfThreads++;
waitForAll();
if(numOfThreads == threadsArray.length)
{
finished = false;
notifyAll();
}
}
public int checkValue(Threads t, int ind) //returns the thread's value to be updated. 1,-1 or 0.
public int getIterations()
{
return this.iterations;
}
public synchronized void finished()
{
numOfThreads--;
notifyAll();
if(numOfThreads == 0)
finished = true;
}
public void iteration()
{
for(int i=0; i < threadsArray.length; i++)
threadsArray[i].start();
}
public synchronized void updated()
{
numOfThreads--;
if(numOfThreads == 0)
{
printResults();
finished = true;
notifyAll();
}
}
public synchronized void waitForAll()
{
while(numOfThreads != threadsArray.length)
{
try{ wait(); }
catch(InterruptedException e) {}
}
}
public void printResults() // prints the result on each iteration.
}

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.

How to avoid that an object knows the collection in which it is contained?

Say I have a object class as follows:
public class MyObject() {
// ...
public double distanceTo(MyObject other) {
// **edit: check if desired distance is contained in distanceMatrix**
// **of the collection in which this object is contained**
// **if not:** some time-consuming calculation
}
}
I also have a custom collection that contains such objects:
public class MyObjectCollection() {
private List<MyObject> objects;
private double[][] distanceMatrix;
// ...
public void add(MyObject obj) {
this.objects.add(obj);
}
public void calcDistanceMatrix() {
for (int i = 0; i < objects.size(); i++) {
for (int j = 0; j < objects.size(); j++) {
this.distanceMatrix[i][j] = objects.get(i).distanceTo(objects.get(j));
}
}
}
}
So the idea is to calculate all the distances between all MyObject's only once and to store them in a matrix. Now when someone calls distanceToon a MyObject, it should use the cached value instead of calculating it again.
However, for this to work, each MyObject must know the collection in which it is contained - or does it? I want to avoid this due to separation.
(I know that I could store all the distances from a MyObject obj1 to other MyObject's as a field in obj1, but I do not want to do this either. For example, this would mean rebuilding the MyObjectCollection structure (which I need anyway for other reasons) for each MyObject.)
I think you need to do 2 things in order to separate time consuming calcultion and dependency from collection:
1) On the MyObject separate the logic that gets cached distance and the that does actual calculation into different methods.
2) Move the logic that gets distance between two object into an interface following Strategy pattern:
Here is the modified code showing it:
public interface DistanceCalc{
public double distanceTo(MyObject from, MyObject to);
}
public class MyObject{
private DistanceCalc distanceCalc = null;
public void setDistanceCalc(DistanceCalc distanceCalc) {
this.distanceCalc = distanceCalc;
}
public double distanceTo(MyObject other) {
return distanceCalc.distanceTo(this, other);
}
public double calculateDistance(MyObject to) {
return 5.0; //this is where time consuming calculation happens
}
}
public class MyObjectCollection implements DistanceCalc{
private List<MyObject> objects;
private double[][] distanceMatrix;
public void add(MyObject obj) {
this.objects.add(obj);
obj.setDistanceCalc(this);
}
#Override
public double distanceTo(MyObject from, MyObject to) {
if (distanceMatrix == null) calcDistanceMatrix();
return distanceMatrix[ objects.indexOf(from) ][ objects.indexOf(to) ];
}
public void calcDistanceMatrix() {
for (int i = 0; i < objects.size(); i++) {
for (int j = 0; j < objects.size(); j++) {
this.distanceMatrix[i][j] = objects.get(i).calculateDistance( objects.get(j) );
}
}
}
}

Multithreading doesn't work. What is incorrect?

It's a little program written with a purpose of studying multithreading. I expected to get in main method different random numbers after run. About 4 numbers per second. But I got many thousands of zeros. Where is an error?
Main Class:
public class Main {
public static void main(String[] args) {
ExternalWorld externalWorld = new ExternalWorld();
externalWorld.start();
int x = 0;
while (true) {
while(!externalWorld.signal){
System.out.println("qqq");}
System.out.println(++x + ") " + externalWorld.getAnInt());
}
}
}
ExternalWorld Class:
import java.util.Random;
public class ExternalWorld extends Thread {
private int anInt = 0;
public boolean signal = false;
#Override
public void run() {
Random random = new Random(100);
while(true) {
anInt = random.nextInt(100);
signal = true;
try {
Thread.sleep(200);
signal = false;
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public int getAnInt() {
if (!signal) {
int p = 1 / 0;
}
int result = anInt;
anInt = 0;
return result;
}
}
problem:
private int anInt = 0;
public boolean signal = false;
You are access those variables from one thread to another thus giving you 0 and false on the main thread
solution:
use volatile keyword to access those variables from multiple threads
sample:
private volatile int anInt = 0;
public volatile boolean signal = false;

JUnit - Test Max Number of Objects Created

I have a very small class, BuildThreeObjects, which creates a maximum of 3 Objects using a private int variable, numObjects, to store the count. If the count is < 3, a new Object is returned else null is returned.
Could anyone guide me on how to test if a maximum of 3 Objects are created using JUnit. Looking at the API didn't help much. I assumed assertNotNull or assertNull would be used but I can't think how to.
// Code for BuildThreeObjects class
public class BuildThreeObjects {
private int numObjects = 0;
public Object buildObject() {
if (numObjects<3) {
numObjects++;
return new Object();
}
else return null;
}
}
// Code within the JUnit class; all unnecessary code omitted
private BuildThreeObjects bto;
#Before
public void setUp() throws Exception {
bto = new BuildThreeObjects();
}
#Test
public void testBuild() {
assertNotNull(bto.buildObject());
}
// assertNotNull passes and assertNull fails as it only checks the first object creation
You mean something like this?
class BuildThreeObjects{
int count = 0;
public Object buildObject(){
if(count >= 3){
return null;
} else {
count++;
return new Object();
}
}
}
private BuildThreeObjects bto;
#Before
public void setUp() throws Exception {
bto = new BuildThreeObjects();
}
#Test
public void testBuild() {
assertNotNull(bto.buildObject());
System.out.println(bto.count);
assertNotNull(bto.buildObject());
System.out.println(bto.count);
assertNotNull(bto.buildObject());
System.out.println(bto.count);
assertNull(bto.buildObject());
System.out.println(bto.count);
}
// with for loop
for(int i=0; i < 100; i++){
if(i < 3){
assertNotNull(bto.buildObject());
System.out.println(bto.count);
} else {
assertNull(bto.buildObject());
System.out.println(bto.count);
}
}
Just literally do it:
assertNotNull(createObject());
assertNotNull(createObject());
assertNotNull(createObject());
assertNull(createObject());
you could use for-loop also if it could be more expressive.

Categories

Resources