Java Thread execution on same data - java

first of all here is the code, you can just copy an paste
import java.util.ArrayList;
public class RepetionCounter implements Runnable{
private int x;
private int y;
private int[][] matrix;
private int xCounter;
private int yCounter;
private ArrayList<Thread> threadArray;
private int rowIndex;
private boolean[] countCompleted;
public RepetionCounter(int x, int y, int [][]matrix)
{
this.x = x;
this.y = y;
this.matrix = matrix;
this.threadArray = new ArrayList<Thread>(matrix.length);
this.rowIndex = 0;
for(int i = 0; i < matrix.length; i++){
threadArray.add(new Thread(this));
}
countCompleted = new boolean[matrix.length];
}
public void start(){
for (int i = 0; i < threadArray.size(); i++){
threadArray.get(i).start();
this.rowIndex++;
}
}
public void count(int rowIndex)
{
for(int i = 0; i < matrix[rowIndex].length; i++){
if (matrix[rowIndex][i] == x){
this.xCounter++;
} else if (matrix[rowIndex][i] == y){
this.yCounter++;
}
}
}
#Override
public void run() {
count(this.rowIndex);
countCompleted[this.rowIndex] = true;
}
public int getxCounter() {
return xCounter;
}
public void setxCounter(int xCounter) {
this.xCounter = xCounter;
}
public int getyCounter() {
return yCounter;
}
public void setyCounter(int yCounter) {
this.yCounter = yCounter;
}
public boolean[] getCountCompleted() {
return countCompleted;
}
public void setCountCompleted(boolean[] countCompleted) {
this.countCompleted = countCompleted;
}
public static void main(String args[]){
int[][] matrix = {{0,2,1}, {2,3,4}, {3,2,0}};
RepetionCounter rc = new RepetionCounter(0, 2, matrix);
rc.start();
boolean ready = false;
while(!ready){
for(int i = 0; i < matrix.length; i++){
if (rc.getCountCompleted()[i]){
ready = true;
} else {
ready = false;
}
}
}
if (rc.getxCounter() > rc.getyCounter()){
System.out.println("Thre are more x than y");
} else {System.out.println("There are:"+rc.getxCounter()+" x and:"+rc.getyCounter()+" y");
}
}
}
What I want this code to do: I give to the object a matrix and tow numbers, and I want to know how much times these two numbers occurs in the matrix. I create as many thread as the number of rows of the matrix (that' why there is that ArrayList), so in this object I have k threads (supposing k is the number of rows), each of them count the occurrences of the two numbers.
The problem is: if I run it for the first time everything work, but if I try to execute it another time I get and IndexOutOfBoundException, or a bad count of the occurrences, the odd thing is that if I get the error, and modify the code, after that it will works again just for once.
Can you explain to me why is this happening?

You are using the same instance of RepetitionCounter for each thread:
for(int i = 0; i < matrix.length; i++){
threadArray.add(new Thread(this));
}
so they will all share the same rowIndex. The code is pretty confusing as it is, so I suggest you encapsulate the logic for the threads in a separate Runnable class with individual row ids:
class ThreadTask implements Runnable {
private int rowId;
private int[][] matrix;
public ThreadTask(int[][] matrix, int rowId) {
this.matrix = matrix; // only a reference is passed here so no worries
this.rowId = rowId;
}
public void run() {
// search on my row
}
}
then:
for(int i = 0; i < matrix.length; i++) {
threadArray.add(new Thread(new ThreadTask(matrix, i)));
}

You need to give each thread its own Runnable. Having them all share the same Runnable is going to cause disastrous race conditions. Separate out the logic each thread needs to do into a Runnable. Then move the part of the code that starts up the threads to a place outside the Runnable.
BTW look into Executors in the java.util.concurrent package, you don't have to use raw threads for this stuff. Also using Executors may give you a better idea about separating what goes into the Task from other stuff.

Related

Confusion regarding threads and thread safety

To understand the concept of threads better, we are supposed to use a Number object that can be increased, decreased, squared and rooted via it's methods. It's only attribute is a double number (initialized as number=1).
So if i instantiate the Number object and call increment(), decrement(), square() and root() 100000000 times to that number object, the number attribute is 1 again (as expected).
Now the problem is that we are supposed to instantiate two thread objects, one calling the increase/decrease 100000000 times and the other one calling square/root 100000000 times.
According to our teacher the result would be inconsistency, i.E getting 0 instead of 1 as the result, but in my program it just gives me infinity or 1 depending on wether or not i am using synchronized() in the Thread class.
public class Calculation {
public static void main(String[] args) throws InterruptedException {
Number num = new Number();
Number num1 = new Number();
for (int i = 0; i < 100000000; i++) {
num.increment();
}
for (int i = 0; i < 100000000; i++) {
num.decrement();
}
for (int i = 0; i < 100000000; i++) {
num.square();
}
for (int i = 0; i < 100000000; i++) {
num.root();
}
System.out.println(num.getNumber());
CalcThread t1 = new CalcThread(num1, true);
CalcThread t2 = new CalcThread(num1, false);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(num1.getNumber());
}
}
public class CalcThread extends Thread {
public Number num;
public boolean decision;
public CalcThread(Number num, boolean decision) {
this.num = num;
this.decision = decision;
}
#Override
public void run() {
synchronized(num) {
if (this.decision) {
for (int i = 0; i < 100000000; i++) {
num.square();
}
for (int i = 0; i < 100000000; i++) {
num.root();
}
} else {
for (int i = 0; i < 100000000; i++) {
num.increment();
}
for (int i = 0; i < 100000000; i++) {
num.decrement();
}
}
}
}
}
public class Number {
double number;
public Number() {
this.number = 1;
}
public void increment() {
this.number++;
}
public void decrement() {
this.number--;
}
public void square() {
this.number = this.number * this.number;
}
public void root() {
this.number = Math.sqrt(this.number);
}
public double getNumber() {
return number;
}
public void setNumber(double number) {
this.number = number;
}
}
Getting infinity when leaving synchronized out makes sense because it is increasing while squaring the number at the same time, so the number will soon be too large to fit the double type size right?
How do i get the inconsistency my teacher was talking about?
Thank you for your help in advance.

Java visibility and synchronization - Thinking in Java example

I read now Thinking in Java, chapter about atomicity and visibility. There is an example I don't understand.
public class SerialNumberGenerator {
private static volatile int serialNumber = 0;
public static int nextSerialNumber() {
return serialNumber++;
}
}
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;
}
}
synchronized void add(int i) {
array[index] = i;
index = ++index % len;
}
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();
static class SerialChecker implements Runnable {
#Override
public void run() {
while (true) {
int serial = SerialNumberGenerator.nextSerialNumber();
if (serials.contains(serial)) {
System.out.println("Duplicate: " + serial);
System.exit(0);
}
serials.add(serial);
}
}
}
public static void main(String[] args) throws Exception {
for (int i = 0; i < SIZE; i++) {
exec.execute(new SerialChecker());
}
}
}
example output:
Duplicate: 228
I don't understand how is it possible. Even method nextSerialNumber() is not synchronized and all thread generate different values each thread has own value of serial and each are different. So how is it possible to find duplicate. I cannot imagine of threads execution.
This example shows the post-increment operator is not atomic and not thread-safe.
What happens in this code is:
many (up to 100) threads are started, each executing the same code
in an infinite loop:
an unsynchronized method nextSerialNumber is called, which returns the result of the post-increment operator called on a static variable
a synchronized method contains is called, which checks if the returned value exists in the underlying collection
if yes, the program is terminated
if not, the value is added to the underlying collection
If the post-increment operation was thread-safe then the program would never print "Duplicate" and would never terminate,
since every thread would be getting a different serial number value. This is not the case as two threads
might get exactly the same serial number value.

Division of a task to threads - multi threading

I want to generate pairs from a given large pool of numbers. I am using two for loops and threads. My function getAllPairs() in the code generates apairs with a given array of numbers.
I have an array of length 1000. With one thread, output time is nearly 15 sec. Now I want to use 5-6 threads and reduce this output time.I am stuck at dividing this task equally to five threads.If not threads,how to decrease the output time?
Solution with threads is appreciated since I put a lot of time learning multithreading. I would like to implement it.
import java.util.*;
class Pair {
public int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
#Override
public String toString(){
return " ( " + x + " ," + y + " ) " ;
}
}
class selectPairs{
private int[] array;
private List<Pair> totalPairs ;
public selectPairs(int[] arr){
array = arr;
}
//set Method
public void settotalPairs(List<Pair> pieces){
totalPairs = pieces;
}
//get Method
public List<Pair> gettotalPairs(){
return totalPairs;
}
// Method to generate pairs
public List<Pair> getAllPairs() {
List<Pair> pairs = new ArrayList<Pair>();
int total = array.length;
for(int i=0; i < total; i++) {
int num1 = array[i];
for(int j=i+1; j < total; j++) {
int num2 = array[j];
pairs.add(new Pair(num1,num2));
}
}
return pairs;
}
}
// Thread class
class ThreadPairs extends Thread {
private Thread t;
selectPairs SP;
ThreadPairs(selectPairs sp){
SP = sp;
}
public void run() {
synchronized(SP) {
List<Pair> PAIRS = SP.getAllPairs();
SP.settotalPairs(PAIRS);
}
}
}
public class TestThread {
public static void main(String args[]) {
int[] a = new int[1000];
for (int i = 0; i < a.length; i++) {
a[i] = i ;
}
selectPairs ob = new selectPairs(a);
ThreadPairs T = new ThreadPairs( ob );
T.start();
while (true) {
try {
T.join();
break;
}
catch(Exception e){
}
}
List<Pair> Total = new ArrayList<Pair>() ;
List<Pair> Temp1 = ob.gettotalPairs();
Total.addAll(Temp1);
System.out.println(Total);
}
}
A solution with a thread-pool, a task split strategy and it collects all results:
public class SelectPairs {
private static final int NUM_THREADS = 8;
private int[] array;
public SelectPairs(int[] arr) {
array = arr;
}
// A splitting task strategy
public List<Pair> getPartialPairs(int threadIndex, int numThreads) {
List<Pair> pairs = new ArrayList<Pair>();
int total = array.length;
for (int i = threadIndex; i < total; i += numThreads) {
int num1 = array[i];
for (int j = i + 1; j < total; j++) {
int num2 = array[j];
pairs.add(new Pair(num1, num2));
}
}
return pairs;
}
// To use Callables or Runnables are better than extends a Thread.
public static class PartialPairsCall implements Callable<List<Pair>> {
private int thread;
private int totalThreads;
private SelectPairs selectPairs;
public PartialPairsCall(int thread, int totalThreads, SelectPairs selectPairs) {
this.thread = thread;
this.totalThreads = totalThreads;
this.selectPairs = selectPairs;
}
#Override
public List<Pair> call() throws Exception {
return selectPairs.getPartialPairs(thread, totalThreads);
}
}
public static void main(String[] args) throws Exception {
int[] a = new int[1000];
for (int i = 0; i < a.length; i++) {
a[i] = i;
}
SelectPairs sp = new SelectPairs(a);
// Create a thread pool
ExecutorService es = Executors.newFixedThreadPool(NUM_THREADS);
List<Future<List<Pair>>> futures = new ArrayList<>(NUM_THREADS);
// Submit task to every thread:
for (int i = 0; i < NUM_THREADS; i++) {
futures.add(es.submit(new PartialPairsCall(i, NUM_THREADS, sp)));
}
// Collect the results:
List<Pair> result = new ArrayList<>(a.length * (a.length - 1));
for (Future<List<Pair>> future : futures) {
result.addAll(future.get());
}
// Shutdown thread pool
es.shutdown();
System.out.println("result: " + result.size());
}
}
regarding the framework of multithreading, you can implement ThreadPoolExecutor as was suggested in a comment.
Regarding splitting the workload, it seems that the key is splitting the iteration on the array which is achievable if you give the Runnable task a start and end index to iterate over.

Strange behaviour of synchronized

class TestSync {
public static void main(String[] args) throws InterruptedException {
Counter counter1 = new Counter();
Counter counter2 = new Counter();
Counter counter3 = new Counter();
Counter counter4 = new Counter();
counter1.start();
counter2.start();
counter3.start();
counter4.start();
counter1.join();
counter2.join();
counter3.join();
counter4.join();
for (int i = 1; i <= 100; i++) {
if (values[i] > 1) {
System.out.println(String.format("%d was visited %d times", i, values[i]));
} else if (values[i] == 0) {
System.out.println(String.format("%d wasn't visited", i));
}
}
}
public static Integer count = 0;
public static int[] values = new int[105];
static {
for (int i = 0; i < 105; i++) {
values[i] = 0;
}
}
public static void incrementCount() {
count++;
}
public static int getCount() {
return count;
}
public static class Counter extends Thread {
#Override
public void run() {
do {
synchronized (count) {
incrementCount();
values[getCount()]++;
}
} while (getCount() < 100);
}
}
}
That is a code from one online course. My task is to make this code visit each element of array only once (only for elements from 1 to 100). So I have added simple synchronized block to run method. In case of using values inside of that statement everything works. But with count it doesn't want to work.
What the difference? Both of this objects are static fields inside of the same class. Also I have tried to make count volatile but it hasn't helped me.
PS: a lot of elements are visited 2 times and some of them even 3 times. In case of using values in synchronized all elements are visited only once!!!
Integer is immutable. The moment you call increment method, You get a new object and reference of count variable gets changed and hence leads to an issue.

Bubble Sort Simulation JButton coloring

Im trying to make a program that will help visualize the bubble sort algorithm. The script sorts the array correctly, however it does not allow the JFrame to open until it has finished. Is there a way to make it recolor all of the buttons before moving ahead with its sorting? Posted below is the class that handles the sorting and coloring currently.
public class SortStart {
private JButton[] list;
private int[] randomList;
public SortStart(JButton[] list, int[] randomList){
this.list = list;
this.randomList = randomList;
}
public void run(){
String str = "";
int temp = 0;
int k = 0;
boolean swapped = true;
//Sort the colors
while(swapped){
swapped = false;
k ++;
for(int i = 0; i < randomList.length - k; i ++){
if(randomList[i] > randomList[i+1]){
temp = randomList[i];
randomList[i] = randomList[i+1];
randomList[i+1] = temp;
swapped = true;
for(int l = 0; l < randomList.length; l++){
System.out.print(randomList[l] + ", ");
}
System.out.println();
for(int j = 0; j < randomList.length; j++){
list[j].setBackground(new java.awt.Color(randomList[j],randomList[j],255));
}
}
}
}
}
}
SwingWorker can execute only once, instead make an instance of a Thread with a Runnable class using a PropertyChangeListener to reflect the changes in the view.
You're using the view's thread to run your code so nothing else can execute (repaints) until finished.
In your Runnable class you should define a PropertyChangeSupport object bound to the object been modified. And add the method addPropertyChangeListener (then define a PropertyChangeListener in your view), something like this:
private PropertyChangeSupport mPcs =
new PropertyChangeSupport(this);
public void setMouthWidth(int mw) {
int oldMouthWidth = mMouthWidth;
mMouthWidth = mw;
mPcs.firePropertyChange("mouthWidth", oldMouthWidth, mw); //the modification is "published"
}
public void
addPropertyChangeListener(PropertyChangeListener listener) {
mPcs.addPropertyChangeListener(listener);
}
public void
removePropertyChangeListener(PropertyChangeListener listener) {
mPcs.removePropertyChangeListener(listener);
}

Categories

Resources