Java - ThreadPool synchronized problem when i try printing - java

i use ThreadPool class and when i try to print the matrix this is what i get:
Enter number of threads:
5
Enter number of matrices:
3
Enter number diminesion:
2
[1][1][0][1]
[0][1]
-----------------------------------------------
[0][0]
[1][0]
-----------------------------------------------
[0][1]
-----------------------------------------------
i try to synchronized but is still not working good, why?
and another question, when i try to use matrices queue from GenerateMatrix class in the main is say the queue is empty what id do wrong?
because what i try to do is to generate n matrix and after the generate is finish multiply all the matrices.
main:
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Queue<int[][]> matrices = new LinkedList<int[][]>();
System.out.println("Enter number of threads:");
int numOfThreads = input.nextInt();
ThreadPool pool = new ThreadPool(numOfThreads);
System.out.println("Enter number of matrices:");
int numOfMatrices = input.nextInt();
System.out.println("Enter number diminesion:");
int diminesion = input.nextInt();
for (int i = 0; i < numOfMatrices; i++) {
GenerateMatrix generateMatrix = new GenerateMatrix(numOfMatrices,
diminesion);
pool.execute(generateMatrix);
}
}
}
GenerateMatrix class:
import java.util.LinkedList;
import java.util.Queue;
public class GenerateMatrix implements Runnable {
private int numOfMatrices;
private int dimension;
private static Queue<int[][]> matrices = new LinkedList<int[][]>();
public GenerateMatrix(int n, int d) {
numOfMatrices = n;
dimension = d;
}
public Queue<int[][]> getMatricesQueue() {
return matrices;
}
public void run() {
int[][] tempMatrix = new int[dimension][dimension];
for (int i = 0; i < tempMatrix.length; i++) {
for (int j = 0; j < tempMatrix.length; j++) {
tempMatrix[i][j] = (int) (Math.random() * 2);
}
}
synchronized (this) {
for (int k = 0; k < tempMatrix.length; k++) {
for (int j = 0; j < tempMatrix.length; j++) {
System.out.print("[" + tempMatrix[k][j] + "]");
}
System.out.println();
}
System.out.println("-----------------------------------------------
");
matrices.add(tempMatrix);
}
}
}

The reason why matrices is empty in the class Main is because you never add anything to it. You create 2 variables called matrices, one in Main, one in GenerateMatrices.If you look in Main, you call:
Queue<int[][]> matrices = new LinkedList<int[][]>();
and then you never use it again, so it remains empty. If however you called GenerateMatrices.getMatrices().length, it should be non-zero (assuming you define getMatrices().
As for why it is printing weirdly, the following SO answer should help: Java: System.out.println and System.err.println out of order
In short, calls to System.out.println() are not immediately written to output, due to the high overhead of the system call. Instead, they are written to a buffer and, when the JVM is happy that more isn't going to arrive in the near future, the contents of the buffer is written to output. System.out.flush() forces this process to happen sooner, which may help you with what you need.
Alternatively, instead of using synchronized (this) {...} you can use syncrhonized (System.out) {...} to ensure no interleaving.
P.S.
GenerateMatrices.matrices probably shouldn't be static. If you create multiple instances of GenerateMatrices, you probably want them to have separate copies of matrices. And if not, you should probably create a class such as MatrixStore to make it clear what is happening.

Related

java: how to calculate multiplication between all values in variable difference

I received that task:
"A small method, calculateProduct is to be written. It will ask the user to enter two int values, and then calculate and display the product of all the values between the two values entered. For example if the user enters the numbers 2 and 5 the program will display the result 120 (calculated as 2 * 3 * 4 * 5)"
I tried to build something like this:
import java.util.Scanner;
public class Exam {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a;
int b;
int big;
int small;
//ask to insert two variables
System.out.println("Insert variable a");
a = in.nextInt();
System.out.println ("Insert variable b");
b=in.nextInt();
// compare two variables
// set the biggest variables to b, the smallest - to a
if (a >=b){
big=a;
small=b;
}
else {
big=b;
small=a;
}
// set the do while loop to complete the code. Run multiplying before counter won't fit to b variable
int result = small;
for (int i=small; i<=big;i++){
result*=i;
}
System.out.println("the multiplication progression between "+small+" and "+big+" equals to "+result);
}
}
However, when I insert 2 and 5 the result is 240. Does anybody know how to fix it? thanks!
Change loop to:
for (int i = small + 1; i <= big; i++)
{
result *= i;
}
you init result with small then multiply it by small again.
Fix: Start the for statement with small+1
...
int result = small;
for (int i=small+1; i<=big;i++){
result*=i;
}
....
The other obvious solution here is to change the init statement from
int result = small;
to
int result = 1;
In that case you don't have to touch your looping code.
And for the record: "small" is a rather bad name here, why not call it "smallerInput" or something like that.
Finally: you could avoid dealing with "small" - if a < b you can simply loop from a to b; and otherwise you could loop "backwards" from "b to a".
Just change your for loop as below mentioned will solve your problem.
The problem in your loop is :
In its first iteration it is multiple with itself rather than its
incremented value.
From:
for (int i=small; i<=big;i++)
To:
for (int i=small+1; i<=big;i++)
The task is to write a method called "calculateProduct". Above you are doing all your callculation in your main method. Try to separate that. Example :
import java.util.Scanner;
public class Exam {
public static void main (String[]args) {
Scanner in = new Scanner(System.in);
int a;
int b;
System.out.println("Insert variable a");
a = in.nextInt();
System.out.println ("Insert variable b");
b=in.nextInt();
if(a>=b){
calculateProduct(b,a);
}
else{
calculateProduct(a,b);
}
}
public static void calculateProduct (int m, int n) {
int result = 1;
for (int i = m; i <= n; i++) {
result *= i;
}
System.out.println("the multiplication progression between "+m+" and "+n+" equals to "+result);
}
}

Different random output when run differently

I am trying to solve a problem:-
A point is at an initial position X. It can be shifted either left or right. If it is moved either left or right with equal probability 10 times, what is the probability of it ending up in its initial position X?
I used the following java program:-
import java.util.Random;
public class ProbMain {
int left;
int right;
int error;
double middle;
public ProbMain() {
left = right = error = 0;
middle = 0.0;
}
void pushLeft() {
++left;
}
void pushRight() {
++right;
}
void push() {
int whichWay;
Random rand = new Random();
whichWay = rand.nextInt(2);
if (whichWay == 0)
pushLeft();
else if (whichWay == 1)
pushRight();
else
++error;
}
public static void main(String[] args) {
ProbMain obj = new ProbMain();
for (int b = 0; b < 10000; b++) {
for (int a = 0; a < 10000; a++) {
for (int i = 0; i < 10; i++)
obj.push();
if (obj.left == obj.right)
++obj.middle;
obj.left = obj.right = 0;
}
}
System.out.println("Error: " + obj.error);
System.out.println("Probability of middle: " + obj.middle / (10000*10000));
}
}
Weird thing is that when I run this on Eclipse I get result around 0.05 but when I run from command line I get result around 0.24. Why so? And which one is correct?
You are creating a new Random object each time you want to retrieve a random number (in the push() method) - this can lead to very poor entropy and create strange results when the program is run with different timings - usually running from eclipse will be much slower due to the attached debugger, which will yield better random results when the RNG is initialized with a time value as seed.
You should change your program to use only ONE Random instance, for example by declaring a new Random member variable and initializing it once in your ProbMain constructor.

Smallest number with digits product of n

I need to find the smallest number which digit numbers product is equal to a given num.
import java.util.Scanner;
class timus_1014_2 {
public static void main(String[] args){
int[] arr = new int[10]; // eskan ban# chem imanum inchi a statik,
int prod = 1;
int j = 0;
Scanner in = new Scanner(System.in);
int n = in.nextInt();
for (int i = 2; i < 10; ++i){
if (n % i == 0) {
arr[j] = i;
j++;
}
}
prod = prod * arr[j];
System.out.print(prod);
}
}
Something is wrong with the logic, whats is the problem when I input 10 it should give 25 but it gives 0. Please give ideas of how to make a program find a number which digits product is a given num.
If I understood your problem correctly you need a number whose product of digits equals a number N. Since you asked for new algorithm , you can chck following code.
Logic:
Note : For number whose prime factors are less than 10
Get all factors from 9 -> 2
add to list
print in reverse or use stack instead of list
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter number");
int num = in.nextInt();
List<Integer> lst = new ArrayList<>();
for (int p = 9; p >= 2; p--) {
while (num % p == 0) {
num /= p;
lst.add(p);
}
}
String smallestNumber = "";
for (int i = lst.size() - 1; i >= 0; i--) {
smallestNumber = smallestNumber + lst.get(i);
}
System.out.println("Smallest number : " + smallestNumber);
}
}
Output :
Enter number
10
Smallest number : 25
Enter number
144
Smallest number : 289
Enter number
12
Smallest number : 26
I suggest you look at each error is fix it one by one. I also suggest you use an IDE which will show you the errors and you type and will help ensure you don't have an overwhelming number of errors and you can see if those error disappear based on your corrections.
BTW Often when you use an array for a short piece of code, it can often be eliminate as I suspect it can be removed in your case.
Static methods can not access non-static members of class.
In your case prod is member variable of class but not static. To fix the error , try to make prod as static.
private static int prod = 1;
I would prefer , to make it local variable if no other method is using it.
The problem here is you need to create an object of the particular class to call a particular method associated with it
import java.util.Scanner;
class DigPro {
static int[] arr = new int[10]; // eskan ban# chem imanum inchi a statik,
int prod = 1;
public static void main(String[] args){
Scanner in = new Scanner(System.in);
DigPro obj = new DigPro();
obj.prime(in.nextInt());
}
public void prime(int n){
for (int i = 1; i < 10; ++i){
for (int j = 0; j < 9; ++j) {
if (n % i == 0) {
arr[j] = i;
}
prod = prod * arr[j];
}
}
System.out.print(prod);
}
}
Here you need to create an object say obj of DigPro class and then call prime(int n) method with that object. Also your division is startint with zero which is changed to one
In above code you are increasing j after the assigning value to arr[j].You should do the following:-
prod = prod * arr[j-1];
Here it will multiply prod with last array updated. That is why you are getting zero. And for your another question find the smallest number which digit numbers product is equal to a given num has similar answer at this link.
Since this is actually a pretty interesting problem, I took the time to come up with a correct solution for all possible integer inputs.
import java.util.*;
public class Main{
public static void main(String[] args) {
System.out.println("Enter number:");
int number = new Scanner(System.in).nextInt();
Stack<String> factors = new Stack<>();
if(number==0){
factors.push("0");
}else if(number==1){
factors.push("1");
}else{
for(int f=9;f>1;f--){
while(number%f==0){
factors.push(Integer.toString(f));
number/=f;
}
}
}
if(number<0){
factors.push("-");
}
if(number>9){
System.out.println("This is impossible.");
}else{
System.out.println("Smallest Number:");
while(!factors.empty()) System.out.print(factors.pop());
}
}
}

n! BigInteger makes a loop

I've written this little program to find n!:
public class Fattoriale {
public static void main (String[] args){
int n;
do {
n = Input.readInt("Enter an int number ( int >=0)");
while( n < 0);
long fatt = 1;
for (int i = 2; i <= n; i++){
fatta = fatt * i;
}
System.out.println(n"+!" + " = " + fatt);
Now I'm trying to rewrite this program using BigInteger. I've written this:
import jbook.util.*;
import java.math.*;
public class Fattoriale {
public static void main (String[] args){
String s = Input.readString("Enter an int number. ");
BigInteger big = new BigInteger(s);
BigInteger tot = new BigInteger("1");
BigInteger i = new BigInteger("2");
for (; i.compareTo(big) < 0; i.add(BigInteger.ONE)){
tot = tot.multiply(i);
}
System.out.println(tot);
}
}
But this program with BigInteger makes a loop and I can't understand why. I hope somebody can help me. Thank you very much ;). (nb. ignore Input class, it's only a class that I created to enter input faster)
This should be like this because i.add(BigInteger.ONE) doesn't update the variable i.
for (; i.compareTo(big) <= 0; i=i.add(BigInteger.ONE)) {
tot = tot.multiply(i);
}
There are two changes:
It should be <=0 instead of <0
Assign it back to i to update it.
How to confirm?
BigInteger i = new BigInteger("2");
System.out.println(i.add(BigInteger.ONE)); // print 3
System.out.println(i); // print 2
BigInteger is immutable, so unless you set a new value for it using the = operator, its value doesn't change. Thus, each time in the loop that you call i.add(BigInteger.ONE), the computer calculates i+1 and then throws away the result. Instead, try:
for (; i.compareTo(big) < 0; i=i.add(BigInteger.ONE)){

Java issues with for loops

I am having an issue with a dice rolling program that I'm trying to create (just uses console).
Here is the dice rolling class file itself:
import java.util.Random;
public class rtd
{
public static int[] rollthedice(int numSides, int numRolls)
{
int[] rollCounter = new int[numSides];
for (int counter = 0; counter < numRolls; counter++)
{
Random randRoll = new Random();
int die = randRoll.nextInt(numSides) + 1;
if ((counter + 1) == die)
{
rollCounter[counter] = die;
}
}
return rollCounter;
}
}
The problem with the class is that for some reason, the for loop refuses to function when I am testing the class to see if it works with the following class in the same folder:
public class tester
{
public static void main(String[] args)
{
rtd roller = new rtd();
int[] results = new int[6];
results = rtd.rollthedice(6, 20);
int rollNumber = 1;
for (int counter = 0; counter < results.length; counter++)
{
System.out.println(rollNumber + " " + results[counter]);
rollNumber++;
}
}
}
When I run the "tester" class, the results show that only one roll was completed, meaning that the for loop did not repeat the code for the specified number of rolls. Can anyone offer me a possible solution or explanation? If you see other flaws, let me know.
I believe the issue may be in my IDE (BlueJ).
First of all, you should follow the naming conventions of the language. I know you just started. Please find time to read.
I modified your code without changing the class and method names even though I wanted to. I will leave it to you as an exercise.
Here's the modified version of rtd class. Please see the comments in source code.
public class rtd
{
public static int[] rollthedice(int numSides, int numRolls)
{
// An array of total number of rolls (NOT sides) to save the result of all rolls
int[] rollCounter = new int[numRolls];
// Let's roll n-th times where n is numRolls
for (int counter = 0; counter < numRolls; counter++)
{
// Let's get a random number between 1 to numSides (A die usually has 6 sides with 1 to 6 dots)
int randomSide = getRand(1, numSides);
// Let's store the current roll result in array
rollCounter[counter] = randomSide;
}
return rollCounter;
}
/**
* This method returns a number between a given range inclusive
*/
public static int getRand(int min, int max)
{
return min + (int)(Math.random() * ((max - min) + 1));
}
}
Also, you can improve your tester class like this-
public class tester
{
public static void main(String[] args)
{
int[] results = rtd.rollthedice(6, 20);
// Since counter starts with 0, we always add 1 so we can read from 1 to 20
for (int counter = 0; counter < results.length; counter++)
{
System.out.println("Roll Number: " + (counter + 1) + " Side Picked: " + results[counter]);
}
}
}
The comments in source should be pretty easy to understand. If you have questions, please ask.

Categories

Resources