Interference problems in program - java

Hi for my java revision I'm going through past paper questions and I'm stuck. I'm given this code:
class FriendFinderThread extends Thread {
// number of FriendBook friends
int numFriends = 0;
public void run() {
// join, then leave FriendBook
FriendBook.join(this);
try { Thread.sleep(10000); }
catch (InterruptedException(ie) {}
FriendBook.leave(this);
}
}
class FriendBook {
// list of FriendBook members
static Vector<FriendFinderThread> members =
new Vector<FriendFinderThread>();
static void join(FriendFinderThread f) {
// add a new friend to all existing members
int size = members.size();
for (int i = 0; i < size; i++) {
members.elementAt(i).numFriends++;
}
f.numFriends = size; // new member’s friends
members.add(f); // add to list of members
}
static void leave(FriendFinderThread f) {
members.remove(f); // remove from list
int size = members.size();
for (int i = 0; i < size; i++) {
members.elementAt(i).numFriends--;
}
}
public static void main() {
for (int n = 0; n < 100; n++) {
new FriendFinderThread().start();
}
}
}
I'm having real trouble understanding what is going on, could someone please explain what is happening in the code and how the code could have problems with interference.
Thank you

At some point one thread will call join. This uses members.size() and accesses each element in members. While doing so another member will leave (the later threads will be slower as they loop over more elements, so at some point there will be more leaving than joining). This means that members.elementAt(members.size()-1) will throw an error.

Related

Threads changing the same Variable wont synchronize [duplicate]

This question already has answers here:
Thread safety in java multithreading
(3 answers)
Difference between volatile and synchronized in Java
(4 answers)
Closed 1 year ago.
My problem is that the code should increment a 1000 times and then output it. But sometimes a isn't 1000 at the end.
public class Counter extends Thread {
private static Integer a = 0;
public void run() {
for (int i = 0; i < 100; i++) {
a++;
}
}
public static void main(String[] args) {
Counter[] ca = new Counter[10];
for (int i = 0; i < 10; i++) {
ca[i] = new Counter();
ca[i].start();
}
for (Counter c : ca) {
try {
c.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(a);
}
This code is the original code that is obviously not going to work because I have multiple Threads accessing the variable a. I've tried putting a synchronized(this) around a++; and marking a as volatile but I still sometimes get a false Result. The only way I've found to make it work reliably it to put join() into the for loop, but that kind of defeats the point of using Threads in the first place.
Any help is appreciated.
There are several problems in the code you posted, and all them a reported in the comments to your qestion.
I try to show the major ones:
Variable a is Integer which is immutable, this means that a++ really means create a new Ineger instance containing the old value plus 1.
the variable a is updated by multiple threads concurrenlty without synchonizazion, this means that the operation a=a+1 canbe split in read a, increment a; if two or more thread read a at the same time the the increment by one the same value
Here is a modified version that uses a Lock to synchronize access to the resource. The main scope of this code is to show that the access to a must be synchronixed between thread; in order to get a "clean design" you must refactor/change a lot of other things.
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SyncProblem {
private static int a=0;
private static class IncThread extends Thread {
private Lock lock;
public IncThread(Lock lock) {
this.lock=lock;
}
public void run() {
lock.lock();
try {
for (int i = 0; i < 100; i++) {
a++;
}
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
Lock lock= new ReentrantLock();
IncThread[] ca = new IncThread[10];
for (int i = 0; i < 10; i++) {
ca[i] = new IncThread(lock);
ca[i].start();
}
for (IncThread c : ca) {
try {
c.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(a);
}
}

Individually/separately instantiated objects using the same data structure

Note: This is a troubling problem, possibly a bug, although I might be incorrect and missing something small
Problem:
Issue is the separately instantiated objects are referring to the same data structure.
Calling a.add() adds an object to data[NEXT], where is instantiated to NEXT = 0, followed by NEXT++ for increment purposes.
Thereafter, b.add() is called, and following the logic of the add() method, the array is extended,
BUT no initial value has been inserted into b i.e. b.data[0] = null
TL;DR
a.add() adds value to a.
b.add() extends a's array. This should not happen as a and b are 2 separate objects of the same type
main class code:
//...
SimpleSet<Integer> a = new SimpleSet<>();
SimpleSet<Integer> b = new SimpleSet<>();
// add a maximum of 20 unique random numbers from 0..99
Random rand = new Random();
for (int i = 0; i < 20; i++) {
a.add(rand.nextInt(100)); //i=0 - adds to data[0] with no issue
b.add(rand.nextInt(100)); //i=0 - extends a's array? why?
}
//...
class SimpleSet
public class SimpleSet<E> {
private static int MIN_SIZE = 1;
private static int NEXT = 0;
private Object[] data;
/**
* constructor of SimpleSet
*/
public SimpleSet() {
data = new Object[MIN_SIZE];
}
public void add(E e) {
if(NEXT > 0.75*MIN_SIZE){
extendArray();
}
if (data != null) {
data[NEXT] = e;
NEXT++;
}
}
private void extendArray() {
MIN_SIZE = MIN_SIZE*2;
Object[] newData = new Object[MIN_SIZE];
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
data = newData;
return;
}
//...
}
Am I missing something small or is this a bug?
IDE = IntelliJ 2016.3

How do I implement a reset for my loop counter?

I have an action listener that calls some methods and one of those methods counts the number of times that a loop inside of another method is run. The problem I am having is that the counter just adds to itself (I understand why I just don't know how to fix it) rather than resetting back to 0.
Here is my action listener code.
public double computeIterative(double n) throws InvalidInput {
int a=1, b=2;
int result = 0;
if (n>=0) {
if(n==0)return 0;
if(n==1)return 1;
if(n==2)return 2;
for(int i = 3; i <= n; i++) {
result = a+(2*b);
a=b;
b = result;
this.getEfficiency();
}
} else{
throw new InvalidInput();
}
return result;
}
ActionListener that calls methods and sets text:
public void actionPerformed(ActionEvent e) {
int n = Integer.parseInt(nField.getText());
//Try Catch for Iterate Radio Button
if (iterateBtn.isSelected()){
try {
double result = sequence.computeIterative(n);
int efficiency = sequence.getEfficiency();
rField.setText(Double.toString(result));
eField.setText(Integer.toString(efficiency));
}
catch (InvalidInput ex) {
}
}
The getEfficiency method counts how many times the loop inside computeIterative method is run and then sets it to a textField.
Here is my getEfficiency method:
public int getEfficiency() {
efficiency++;
return efficiency;
}
Now obviously this will just keep adding onto itself, and I am sure that I am looking way too hard for a solution but I just cant figure it out.
Basically, after the try, catch, I need to set efficiency to 0 so that the next time the computeIterative(n) method is called, I get a proper reading.
You could simply add a method resetEfficiency():
public int resetEfficiency() {
efficiency = 0;
}
And then call it at the beginning of computeIterative():
public double computeIterative(double n) throws InvalidInput {
this.resetEfficiency();
//rest of code goes here
//....
}
(Of course I'm assuming this is not multi-threaded or anything).
public double computeIterative(double n) throws InvalidInput {
int a=1, b=2;
int result = 0;
this.resetEfficiencyCounter(); //Call Reset if Number Got Invalid.
if (n>=0) {
if(n==0)return 0;
if(n==1)return 1;
if(n==2)return 2;
for(int i = 3; i <= n; i++) {
result = a+(2*b);
a=b;
b = result;
this.getEfficiency();
}
} else{
throw new InvalidInput();
}
return result;
}
add new Function Named resetEfficiencyCounter().
private void resetEfficiencyCounter(){
this.efficiency = 0;
}

How do I create a program that does an A* search to solve an 8 puzzle all in one Java Source file?

I have to make a program that takes in an 8 puzzle as an array, checks to see if it is solvable (and catches any input errors), and then uses A* search to solve the puzzle if it is solvable, displaying the sequence of moves to solve the 8 puzzle (basically how the array is reorganized, and this all has to be in one .java file (most I have seen are in multiple source files, which I would have preferred, but that isn't what is being accepted currently. I have gotten most of it done, except for using a file for input to create the puzzle array (I have set it up to take in keyboard input to create it), the A* search algorithm itself, and outputting to file. The parts I have done are pretty much all the validation methods (checking to make sure the puzzle is a true 8 puzzle, uses combination of if statements and try-catch blocks), the checking for solvability method, puzzle creation, and I think that is most of every thing.
The part I am having trouble with is the algorithm itself. I understand it, but not how to implement it all in one file because I don't know how to make a Node object with a State object(I think State is supposed to be an object, but I am not sure) work in the same file as another class object (that class object being puzzle). I have quite a bit done already, but the method that this whole thing is about (I know how to implement this as separate .java files, but not like this, partly due to Java not being my strongest data structure language (my knowledge of java data structure creation is inferior to that using C++). Anyway, here is what I have so far so you can know the context in which I'm working:
import java.io.File;
import java.io.IOException;
import java.util.Queue;
import java.util.Scanner;
public class Puzzle {
public static void main(String[] args) throws IOException
{
int collumnInput = 0;
int rowInput = 0;
if (args.length == 0)
{
System.out.println("Give 8-puzzle as 3x3 matrix (a space between digits, hit Enter after each line: " );
Scanner scan = new Scanner (System.in);
int[][] puzzleArray = new int[3][3];
for (collumnInput=0; collumnInput < 3; collumnInput++)
{
for (rowInput = 0; rowInput < 3; rowInput++)
{
try
{
puzzleArray[collumnInput][rowInput] = scan.nextInt();
if ((puzzleArray[collumnInput][rowInput] > 8) || (puzzleArray[collumnInput][rowInput] < 0))
{
System.out.println("Invalid 8-puzzle entered!");
System.exit(0);
}
}
catch (java.util.InputMismatchException exception)
{
System.out.println("Invalid 8-puzzle entered!");
System.exit(0);
}
}
}
scan.close();
for(int column = 0; column < 3; column++)
{
for(int row = 0; row < 3; row++)
{
System.out.print(puzzleArray[column][row] + " "); //Outputs the array in a 3x3 grid.
}
System.out.println();
}
boolean []check = new boolean[9];
for (int collumnCheck = 0; collumnCheck < collumnInput; collumnCheck++){
for (int rowCheck = 0; rowCheck < rowInput; rowCheck++)
{
if (check[puzzleArray[collumnCheck][rowCheck]]){
System.out.println("Invalid 8-puzzle entered!");
System.exit(0);
}else
{
check[ puzzleArray[collumnCheck][rowCheck]] = true;
}
}
}
int[] oneDArray = convertToOneD(puzzleArray);
boolean possible=isSolvable(oneDArray);
if (possible == true)
System.out.println("Is solvable");
else
System.out.println("Not solvable");
}
/*else if (args.length == 1)
{
}
else if (args.length == 2)
{
}
else
{
System.out.println("Invalid number of arguments, halting execution.");
}
*/
}
public static boolean isSolvable(int [] p)
{
int i, j, n, inversions = 0;
n = p.length;
for(i = 0; i < n - 1; i++)
for(j = i+1; j < n; j++)
if(p[i] > p[j]) {
//System.out.println("("+p[i]+", "+p[j]+")");
inversions++;
}
//System.out.println("Number of inversions are: "+inversions);
return !((inversions > 0) && (inversions % 2 == 0));
}
public static int[] convertToOneD(int[][] theArray)
{
int[] singleD = new int[9];
int k=0;
for (int i=0; i < 3; i++)
{
for (int j=0; j < 3; j++)
{
singleD[k] = theArray[i][j];
k++;
}
}
for (k = 0; k < 9; k++)
{
System.out.print(singleD[k]+" ");
}
return singleD;
}
/*public static void AStarSearch(int[]puzzleArray)
{
}*/
}
Put your other classes inside your Puzzle class as inner static classes, like this:
public class Puzzle {
public static class Node {
public Node() {
//constructor
}
//other methods of Node
}
public static class State {
public State() {
//constructor
}
//other methods of State
}
public static void main(String[] args) {
Node n = new Node();
State s = new State();
//whatever
}
}
You can then use them pretty much as if they were defined in other files. The only difference is that you can't use them from outside the Puzzle class unless they have enough visibility (fine in this case because I've declared them as public) and unless you refer to them as Puzzle.Node or import them.
If they were private, then you could use them inside Puzzle, but not elsewhere.

removing a column from a 2d array

I am trying to write a class that will remove a column from a 2d array, but I keep running into errors that I don't understand. I think I am misunderstanding something very basic here, any help would be appreciated
public class CollumnSwitch
{
int[][] matrix;
int temp;
public static void coldel(int[][] args,int col)
{
for(int i =0;i<args.length;i++)
{
int[][] nargs = new int[args.length][args[i].length-1];
for(int j =0;j<args[i].length;j++)
{
if(j!=col)
{
int temp = args[i][j];
}
nargs[i][j]= temp;
}
}
}
public void printArgs()
{
for(int i =0;i<nargs.length;i++)
{
for(int j =0;j<nargs[i].length;j++)
{
System.out.print(nargs[i][j]);
}
System.out.println();
}
}
}
You cannot access a non-static variable from a static context, you need to change int temp; to static int temp; or you can remove static from your method declaration.
You declare your nargs array in the coldel method, so it is not accessible from other methods. Meaning this doesn't work:
for(int i =0;i<nargs.length;i++) //You try to access nargs which is not possible.
{
for(int j =0;j<nargs[i].length;j++)
...
Maybe you want it to be the matrix array you have in your class? Like this:
in coldel:
matrix= new int[args.length][args[i].length-1];
and in printArgs
for(int i =0;i<matrix.length;i++)
{
for(int j =0;j<matrix[i].length;j++)
...
This require matrix to be static also (again, you can also remove static from coldel)
you can try like this:
static int[][] nargs;
public static void deleteColumn(int[][] args,int col)
{
if(args != null && args.length > 0 && args[0].length > col)
{
nargs = new int[args.length][args[0].length-1];
for(int i =0;i<args.length;i++)
{
int newColIdx = 0;
for(int j =0;j<args[i].length;j++)
{
if(j!=col)
{
nargs[i][newColIdx] = args[i][j];
newColIdx++;
}
}
}
}
}
public static void printArgs()
{
if(nargs != null)
{
for(int i =0;i<nargs.length;i++)
{
for(int j =0;j<nargs[i].length;j++)
{
System.out.print(nargs[i][j] + " ");
}
System.out.println();
}
}
}
Your difficulties are arising due to using variables outside of their scope. In java, variables basically only exist within the most immediate pair of braces from which they were declared. So, for example:
public class Foo {
int classVar; // classVar is visible by all code within this class
public void bar() {
classVar = classVar + 1; // you can read and modify (almost) all variables within your scope
int methodVar = 0; // methodVar is visible to all code within this method
if(methodVar == classVar) {
int ifVar = methodVar * classVar; // ifVar is visible to code within this if statement - but not inside any else or else if blocks
for(int i = 0; i < 100; i++) {
int iterationVar = 0; // iterationVar is created and set to 0 100 times during this loop.
// i is only initialized once, but is not visible outside the for loop
}
// at this point, methodVar and classVar are within scope,
// but ifVar, i, and iterationVar are not
}
public void shoo() {
classVar++; // shoo can see classVar, but no variables that were declared in foo - methodVar, ifVar, iterationVar
}
}
The problem you are having is because you are declaring a new 2-d array for each iteration of the for loop and writing one column to it, before throwing that away, creating a new array, and repeating the process.

Categories