I want to generate a list of unique random numbers from a given input range using threads in Java. For example, given a range of 1-4, I would run 4 threads and each thread would generate a random number such that no two threads would produce the same value twice. I presume I need to implement some synchronization or something? I've tried using Join() but it doesn't seem to work.
My constructor uses input values to populate an array list with a given range. In the run method, I generate a random value (from the same range) and check if it's in the list. If it is, I remove it from the list and print the value. The idea is that when another thread comes in, it can't generate that same value again.
Here is what I have so far:
public class Main {
public static void main(String[] args) {
randomThreadGen randomRange = new randomThreadGen(1, 2);
Thread thread1 = new Thread(randomRange);
Thread thread2 = new Thread(randomRange);
thread1.start();
try {
thread1.join();
} catch (InterruptedException e) {
}
thread2.start();
}
}
And this:
public class randomThreadGen implements Runnable {
private int lowerBound;
private int upperBound;
private final ArrayList<Integer> List = new ArrayList<Integer>();
public randomThreadGen(int lowerb, int upperb) {
this.lowerBound = lowerb;
this.upperBound = upperb;
for (int i = lowerb; i < upperb + 1; i++) { // populate list with values based on lower and upperbounds specified from main
List.add(i);
}
}
#Override
public void run() {
// generate random value
// check if in list. If in list, remove it
// print value
// otherwise try again
int val = ThreadLocalRandom.current().nextInt(lowerBound, upperBound+1); // generate random value based on lower and upper bound inputs from main
while(true){
if(List.contains(val)){
List.remove(new Integer(val));
System.out.println("Random value for " + Thread.currentThread().getName() + " " + val);
System.out.println("List values: " + List);
}
break;
}
}
}'''
This test case with a low range is to make testing easy. Sometimes it works, and Thread0 will generate a different value to Thread01 (1 and 2 or 2 and 1 for example). But sometimes it doesn't (seemingly they generate the same value, in which case my code only prints one value) For example, "Thread02 1" and nothing else.
Any ideas? Is there another way to do this other than join()?
It's quite an easy task. Just use a concurrent hashmap to prevent duplicates. Make sure to declare boundary int and the hashmap as final. Thread.join is needed to guarantee that the results will be printed after all threads have complete their work. There are other effective techniques to replace join but they are not for novices.
Try this:
import java.util.concurrent.ThreadLocalRandom;
import java.util.*;
import java.util.concurrent.*;
public class Main {
final static int low = 0;
final static int up = 5;
final static Set < Integer > inthashmap = ConcurrentHashMap.newKeySet();
// threadhashmap is needed to track down all threads generating ints
final static Set < Thread > threadhashmap = ConcurrentHashMap.newKeySet();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < up - low + 1; i++) {
Thread t = new Thread() {
public void run() {
int randomNum;
try {
randomNum = ThreadLocalRandom.current().nextInt(low, up + 1);
inthashmap.add(randomNum);
System.out.println("A new random int generated : " + randomNum);
} finally {
}
}
};
threadhashmap.add(t);
t.start();
}
//by iterating through all threads in threadhashmap
// and joining them we guarantee that all threads were completed
// before we print the results of work of those threads (i.e. ints)
Iterator<Thread> iterator = threadhashmap.iterator();
while (iterator.hasNext())
iterator.next().join();
System.out.println("Unique ints from hashmap:");
inthashmap.forEach(System.out::println);
}
}
Output:
A new random int generated : 2
A new random int generated : 3
A new random int generated : 3
A new random int generated : 0
A new random int generated : 0
A new random int generated : 2
Unique ints from hashmap:
0
2
3
I want to try practicing avoiding using static methods/variables when not needed, because I've heard/seen/been told that you want to avoid using them when you can. I decided to make a simple password cracker in Java:
import java.util.Random;
public class PasswordCracker
{
public static void main(String args[])
{
PasswordCracker pwcSimulation = new PasswordCracker();
long totalTimeSpentCracking = 0;
int numSimulations = 100;
for(int i = 0; i < numSimulations; i++)
{
System.out.println(pwcSimulation.PasswordCrackingSimulation());
}
}
long PasswordCrackingSimulation()
{
long startTime = System.currentTimeMillis();
int upperBound = 999999;
Random rand = new Random();
int randomPassword = rand.nextInt(upperBound);
int passwordGuess;
for(int i = 0; i <= upperBound; i++)
{
passwordGuess = i;
if(passwordGuess == randomPassword)
{
System.out.println("password Guessed correctly, the password was: " + randomPassword);
break;
}
/*else
{
System.out.println("Your inputted password is incorrect, please try again.");
}*/
}
long endTime = System.currentTimeMillis();
long timeSpentCracking = (endTime - startTime);
System.out.println("The program took " + timeSpentCracking + "ms OR ~" + ((timeSpentCracking/1000) % 60) + " seconds to complete");
return timeSpentCracking;
}
}
first instantiated a new class (hopefully i did this they way you should?) to avoid having to use a static method for the method PasswordCrackingSimulation. Now i'm having trouble returning a value from the method. The printline in the loop will always print 0, so I know that it isn't taking the returned value in the method. Any help would be lovely :) just trying to learn
No, you're doing everything correctly.
You're returning how long it takes in milliseconds to crack that password.
The answer is less than 1 millisecond. That 0 you see? That's because your method is returning 0. It is doing that because endTime - startTime is zero.
Just write return 1 to test this out yourself - you'll see your print loop print 1 instead.
I have a problem running this java code that simulates the work of a CPU.It serves processes using round robin method . I got the code from a reference and it is exactly what i need but unfortunately its not running and throws this exception :
Exception in thread "main" java.lang.NoClassDefFoundError: optimization/Lmder_fcn
at umontreal.iro.lecuyer.probdist.StudentDist.inverseF(StudentDist.java:278)
at umontreal.iro.lecuyer.stat.Tally.confidenceIntervalStudent(Tally.java:294)
at umontreal.iro.lecuyer.stat.Tally.formatCIStudent(Tally.java:359)
at umontreal.iro.lecuyer.stat.Tally.report(Tally.java:497)
here is the code :
package timeshared;
import umontreal.iro.lecuyer.simevents.*;
import umontreal.iro.lecuyer.simprocs.*;
import umontreal.iro.lecuyer.rng.*;
import umontreal.iro.lecuyer.randvar.*;
import umontreal.iro.lecuyer.stat.Tally;
import java.io.*;
public class RoundRobinQueue {
int NumberOfTermainals = 20; // Number of terminals.
double q; // Quantum size.
double overhead = 0.001; // Amount of overhead (h).
double meanThinkingTime = 5.0; // Mean thinking time.
double alpha = 0.5; // Parameters of the Weibull service times.
double lambda = 1.0; // ''
double delta = 0.0; // ''
int N = 1100; // Total number of tasks to simulate.
int N0 = 100; // Number of tasks for warmup.
int NumberOfTasks; // Number of tasks ended so far.
RandomStream streamThink = new MRG32k3a();
RandomVariateGen genThink = new ExponentialGen(streamThink, 1.0 / meanThinkingTime);
RandomStream streamServ = new MRG32k3a("Gen. for service requirements");
RandomVariateGen genServ = new WeibullGen(streamServ, alpha, lambda, delta);
Resource server = new Resource(1, "The server");
Tally meanInRep = new Tally("Average for current run");
Tally statDiff = new Tally("Diff. on mean response times");
class Terminal extends SimProcess {
public void actions() {
double arrivTime; // Arrival time of current request.
double timeNeeded; // Server's time still needed for it.
while (NumberOfTasks < N) {
delay(genThink.nextDouble());
arrivTime = Sim.time();
timeNeeded = genServ.nextDouble();
while (timeNeeded > q) {
server.request(1);
delay(q + overhead);
timeNeeded -= q;
server.release(1);
}
server.request(1); // Here, timeNeeded <= q.
delay(timeNeeded + overhead);
server.release(1);
NumberOfTasks++;
if (NumberOfTasks > N0) meanInRep.add(Sim.time() - arrivTime);
// Take the observation if warmup is over.
}
Sim.stop(); // N tasks have now completed.
}
}
private void simulOneRun() {
SimProcess.init();
server.init();
meanInRep.init();
NumberOfTasks = 0;
for (int i = 1; i <= NumberOfTermainals; i++)
new Terminal().schedule(0.0);
Sim.start();
}
// Simulate numRuns pairs of runs and prints a confidence interval
// on the difference of perf. for q sizes q1 and q2.
public void simulateConfigs(double numRuns, double q1, double q2) {
double mean1; // To memorize average for first configuration.
for (int rep = 0; rep < numRuns; rep++) {
q = q1;
simulOneRun();
mean1 = meanInRep.average();
streamThink.resetStartSubstream();
streamServ.resetStartSubstream();
q = q2;
simulOneRun();
statDiff.add(mean1 - meanInRep.average());
streamThink.resetNextSubstream();
streamServ.resetNextSubstream();
}
statDiff.setConfidenceIntervalStudent();
System.out.println(statDiff.report(0.9, 3));
}
public static void main(String[] args) {
new RoundRobinQueue().simulateConfigs(10, 0.1, 0.2);
}
}
You are missing couple of jar files in your classpath. From the documentation it looks like you would need the following jars.
http://www-labs.iro.umontreal.ca/~simardr/ssj/examples/examples.pdf
colt.jar,Blas.jar,optimization.jar ( this one in particular for your problem),jfreechart-.jar and jcommon-.jar
i fixed the problem , the program needed an optimization library here
to work , i added the jar file and it worked fine
I am compiling a Java program using for loop to find out the biggest value of long. However, nothing was printed when I run the program. Why?
Here's my code:
class LongMaxMin {
public static void main(String args[]) {
long i = 0L;
long result = 0L;
for (; ; ) {
result = i++;
if (i<0)
break;
}
System.out.println("The biggest integer:" + result);
}
Mostly because of time.
A long will have a max of about ~9.22 quintillion. You're starting at zero and incrementing up. That means you need to go through 9 quintillion loops before it wraps over and breaks. I just tried to run 2 billion operations in my javascript console and times out for a couple of minutes before I force quit.
If you sit there and let it run long enough, you'll get your output. Alternatively, start i at something close to the max already, like 9,223,372,036,854,700,000, and see if it still gives you the same issues. In Java 8, adding underscore to numeric literals is allowed. Initializing i to something like 9_223_372_036_854_700_000L will give you something in a more timely manner.
The max long is significantly high, at 9.223372e+18. For specifics, 9,223,372,036,854,775,807 is the number in question. This also contributes to that whole "this works, it'll just take WAY too long" theory.
I was curious how long it would take so I wrote a class to do the same thing. Wrote it with a separate thread to update results to the console every 1 second.
"int" results
1,343,211,433 37.4518434691484288634492200 % left
Max Value: 2,147,483,647
Time Taken (seconds): **1.588**
"long" results
1,220,167,357 99.9999999867709190074470400 % left
2,519,937,368 99.9999999726787843108699600 % left
3,881,970,343 99.9999999579115932059510100 % left
5,210,983,861 99.9999999435023997711689800 % left
6,562,562,290 99.9999999288485570811055300 % left
7,853,387,353 99.9999999148534037050721500 % left
9,137,607,100 99.9999999009298653086103000 % left
10,467,975,104 99.9999998865059865071902600 % left
11,813,910,300 99.9999998719133278719112300 % left
13,183,196,499 99.9999998570674971548090400 % left
...it continues on and on...
1,362,032,97 - difference between the 2nd and 3rd values (1 second)
6,771,768,529 seconds - how many seconds it would take to reach long's max value (Long.MAX_VALUE / 2nd3rdDifference)
6,771,768,529 seconds = 214.73 years (per conversion by google search)
So if my calculations are correct...you'd be dead of old age by the time an average computer calculated the max value of long via incrementing and checking if it's overflowed. Your children would be dead to. Your grandchildren, they might be around when it finished...
Code for Max Value Calculation
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
public class MainLongMaxTest {
// /*
public static final long MAX_VALUE = Long.MAX_VALUE;
public static long value = 0;
public static long previousValue = 0;
// */
/*
public static final int MAX_VALUE = Integer.MAX_VALUE;
public static int value = 0;
public static int previousValue = 0;
*/
public static boolean done;
public static BigDecimal startTime;
public static BigDecimal endTime;
public static void main(String[] args) {
Runnable task = new StatusPrinterRunnable();
new Thread(task).start(); // code waits 1 second before result printing loop
done = false;
startTime = new BigDecimal(System.currentTimeMillis());
while(value >= 0) {
previousValue = value;
value += 1;
}
endTime = new BigDecimal(System.currentTimeMillis());
done = true;
}
}
class StatusPrinterRunnable implements Runnable {
public static final NumberFormat numberFormat = NumberFormat.getNumberInstance();
private static long SLEEP_TIME = 1000;
#Override
public void run() {
try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { throw new RuntimeException(e); }
while(!MainLongMaxTest.done) {
long value = MainLongMaxTest.value;
//long valuesLeft = MAX_VALUE - value;
BigDecimal maxValueBd = new BigDecimal(MainLongMaxTest.MAX_VALUE);
BigDecimal valueBd = new BigDecimal(value);
BigDecimal differenceBd = maxValueBd.subtract(valueBd);
BigDecimal percentLeftBd = differenceBd.divide(maxValueBd, 25, RoundingMode.HALF_DOWN);
percentLeftBd = percentLeftBd.multiply(new BigDecimal(100));
String numberAsString = numberFormat.format(value);
String percentLeftAsString = percentLeftBd.toString();
String message = "" + numberAsString + "\t" + percentLeftAsString + " % left";
System.out.println(message);
try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { throw new RuntimeException(e); }
}
BigDecimal msTaken = MainLongMaxTest.endTime.subtract(MainLongMaxTest.startTime);
BigDecimal secondsTaken = msTaken.divide(new BigDecimal("1000"));
System.out.println();
System.out.println("Max Value: " + numberFormat.format(MainLongMaxTest.previousValue));
System.out.println("Time Taken (seconds): " + secondsTaken);
}
}
I think your logic is correct just it will take a lot of time to reach that value.
the maximum Long value can hold is Long.MAX_value which is 9223372036854775807L
to speed up the logic, I modified the program as below and got the expected result.
public static void main(String args[]) {
long i = 9223372036854775806L;
long result = 0L;
for (; ; ) {
result = i++;
if (i<0) {
System.out.println("result"+result);
System.out.println("i"+i);
break;
}
}
System.out.println("The biggest integer: is" + result);
}
Output:
result9223372036854775807
i-9223372036854775808
The biggest integer: is9223372036854775807
result has the maximum value it can hold after that it changes to its minimum value.
You can get the result in one step if you take advantage of binary algebra by:
result = -1L >>> 1;
Given the following pieces of code, which one is more efficient? The real method returnSomething() can also return 0 in reality so try/catch is needed.
//piece one
long sleepTime = 200;
try{ sleepTime /= returnSomething();}
catch(Exception e){sleepTime = 200;}
private int returnSomething(){
return 1;
}
//or
//piece two
long sleepTime = 200;
if(returnSomething() == 3){sleepTime = 67;}
else if(returnSomething() == 2){sleepTime = 100;}
else if(returnSomething() == 1){sleepTime = 200;}
private int returnSomething(){
return 1;
}
I was trying to figure out which piece of code is more efficient in terms of processor usage, they bot do the same thing. I would like to know if the code I wrote for testing is fit for the purpose or whether I can do other kind of testing on the code. My findings show that piece 2 is 9 times more efficient (9 times less time to execute) even though it uses hard-code if statements and the last if statement is always executed.
Full working program
public class CodePerformanceTester
{
public static void main(String[] args){
CodePerformanceTester tester = new CodePerformanceTester();
tester.start();
}
public void start(){
double start = System.currentTimeMillis();
long sleepTime = 200;
for(int i=0; i<10000000; i++){
//uncoment here the two lines below
//try{ sleepTime /= returnSomething();}
//catch(Exception e){sleepTime = 200;}
//coment the IF STATEMENTS when above code uncomented
if(returnSomething() == 3){sleepTime = 67;}
else if(returnSomething() == 2){sleepTime = 100;}
else if(returnSomething() == 1){sleepTime = 200;}
}
double end = System.currentTimeMillis();
System.out.println("Execution time for 10 million iteration was "+(end-start)+" ms.");
}
private int returnSomething(){
return 1;
}
}
The first piece is probably slower because dividing is more expensive than comparing values.