Why i am getting this output in this java Thread program? - java

Hello i am a beginner in java programming, recently i am studying Threads, i am having problem in output of this program.
class s1 implements Runnable
{
int x = 0, y = 0;
int addX() {x++; return x;}
int addY() {y++; return y;}
public void run() {
for(int i = 0; i < 10; i++){
System.out.println(addX() + " " + addY());
}
}
public static void main(String args[])
{
s1 run1 = new s1();
s1 run2 = new s1();
Thread t1 = new Thread(run1);
Thread t2 = new Thread(run2);
t1.start();
t2.start();
}
}
I am getting output like this,
1 1 2 2 1 1 3 3..., please explain why?

The threads are executing asynchronously - so their output will be naturally intertwined, that's to be expected. In your case:
1 1 2 2 1 1 3 3
...The bit I've "bolded" is the output from one thread, the bit I've left plain is the (start of) the output from the other. I can only work this out because of how the program executes - if you had two threads just printing the character "1" for example, it would be impossible to distinguish what thread was printing what character.
Note that the order in which the numbers appear and the way they intertwine is completely arbitrary - it could have just as easily been something like:
1 1 1 1 2 2 3 3 2 2..
...Or any other possible combination. Don't rely on the order that you happen to get for any particular program, it's completely undefined.

Each instance of the s1 class has its own variables, so they will increment independent of each other. If you only made one instance, the output would be 1 1 2 2 3 3 ....
If you take two threads each printing 1 1 2 2 3 3 ..., you will see the two streams mixed up. As long as it outputs the correct number of each number, in the right order, it is doing what you expect. You cannot expect how the threads will be scheduled.
So, you might see 1 1 2 2 3 3 1 1 2 2 3 3... or 1 1 1 1 2 2 2 2 3 3 3 3... or any other variation.
(You might even get lucky and see 1 1 1 1 2 2 2 2 3 3 3 3 ..., one day, if the scheduler slices in a certain way)
EDIT: Also read this answer on thread-safety within the println call.

Try executing this code:
class Test extends Thread {
Test(String name) {
super(name);
}
int x = 0, y = 0;
int addX() {x++; return x;}
int addY() {y++; return y;}
public void run() {
for(int i = 0; i < 10; i++)
System.out.println(addX() + " " + addY() + ", name:" + getName());
}
public static void main(String args[]) {
Test run1 = new Test("thread1");
Test run2 = new Test("thread2");
run1.start();
run2.start();
}
}
You will get output similar to this one:
1 1, name:thread2
2 2, name:thread2
1 1, name:thread1
2 2, name:thread1
3 3, name:thread2
3 3, name:thread1
That is because treads do not execute synchronously. You don't know when will one be executed. In your code 1 1 and then later again 1 1 is just the output of two threads doing the same thing.

Related

Jagged Array & Nested For Loop in Java

I have what I thought was a very basic code example, but I can't figure out why the code never completes. It seems to stay stuck in a loop. This very simple code is supposed to declare and initialize a jagged array with the first row having 4 columns and the second row having 3 columns. The code asks the user for 7 integers and prints out the result to the screen. All of that works, but it doesn't break out of the loop unless I manually break out of it. If the manual break is used, the correct output is not achieved.
public class TestCode {
public static void main(String[] args) {
//Create new scanner object
Scanner userInput = new Scanner(System.in);
//Declare two dimentional array
int[][] num2d = new int[4][3];
//Declare variables
int i;
int j;
//Print to screen asking for user input
System.out.print("Enter seven numbers: ");
//Loop through array and print the result
for (i = 0; i < num2d.length; i++) {
for (j = 0; j < num2d[i].length; j++) {
num2d[i][j] = userInput.nextInt();
System.out.println(num2d[i][j]);
//break;
}
}
}
}
When I run this code with the break commented out, I get this result, but I have to manually stop it from running.
run:
Enter seven numbers: 1 2 3 4 1 2 3
1
2
3
4
1
2
3
When I put the break in, this is what I get.
run:
Enter seven numbers: 1 2 3 4 1 2 3
1
2
3
4
BUILD SUCCESSFUL (total time: 4 seconds)
What's going on? Why can I get the correct result with the "build successful" message without using the break?
Your code doesn't loop forever: it loops 12 times, because you have declared a 4x3 array - i.e. an array sized 4 where each of the elements is an array of 3 ints.
Instead, I think you want something like this:
int[][] num2d = {new int[4], new int[3]};
your loop runs on the "columns" of the 2d array which is 4 times and for each "column" it runs on its length which is 3. 4 times 3 is 12, and you only enter 7 numbers. the console is always waiting your input.

Java Thread outputting answer wrong

package task1;
import java.lang.Thread;
public class Counter implements Runnable{
int num;
boolean odd;
boolean even;
public Counter(int i,boolean odd, boolean even){
this.num=i;
this.odd=odd;
this.even=even;
}
#Override
public void run() {
if(odd==true&even==false){
System.out.print("\nOdd numbers\n");
for(int j=this.num; j<=10; j+=2){
System.out.print(j + " ");
}
}
else if (odd==true&even==true){
System.out.print("\nEven and odd numbers paired\n");
for(int j=this.num; j<=10; j+=2){
try {
Thread.sleep(600);
} catch (InterruptedException ex) {
System.out.println("The sleeping has been interruped!");
}
System.out.print(j + " " + (j+1)+" | ");
}
}
}
}
class OddEvenNums {
public static void main(String[] args) {
Counter odd = new Counter(1,true,false);
Counter evenodd = new Counter(1,true,true);
Thread oddThread = new Thread(odd);
Thread evenOddThread = new Thread(evenodd);
oddThread.start();
evenOddThread.start();
}
}
Basically this code just has two threads that either print out the odd numbers from 1-10 or print out the odd and the even numbers paired
However the output comes out like
run:
Odd numbers
Even and odd numbers paired
1 3 5 7 9 1 2 | 3 4 | 5 6 | 7 8 | 9 10 |
Instead of what I was hoping for which would be
run:
Odd numbers
1 3 5 7 9
Even and odd numbers paired
1 2 | 3 4 | 5 6 | 7 8 | 9 10 |
I am confused about what I have done wrong to cause it to be outputted like this
Both Threads are running in parallel, not one after another (that's the purpose of Threads in the first place). That's why their output gets mixed up.
Trying to explain the output that you're seeing: The "odd" Thread gets a tiny bit of a head start, letting it print "Odd numbers" first. Then the "oddeven" Thread kicks in and prints "Event and odd numbers paired". Next thing, "oddeven" sleeps for 600 milliseconds (= half an eternity in computer time), giving "odd" all the time it needs to complete printing its sequence. Once the 600ms are elapsed, "oddeven" kicks back in and prints its own sequence (delaying another 600ms between each pair, but that doesn't really matter any more, as "odd" has long completed).
This is by no means deterministic, though. Meaning, if you run the program a couple of times you might see completely different sequences of String output.
The output is totally expected, although it is a bit random in what order exactly stuff happens. What is happening here is:
oddThread writes "Odd numbers"
evenOddThread writes "Even and odd numbers paired"
oddThread writes "1 3 5 7 9" (without newline)
evenOddThread writes "1 2 | 3 4 | 5 6 | 7 8 | 9 10 |"
So, you did nothing wrong per se. But you didn't think about what would happen when you run both threads concurrently. Either don't do that (wait for oddThread to be finished before starting evenOddThread, by calling oddThread.join()), or put some synchronization in there to make sure the output is written atomically. You are somewhat lucky to get the output you got. I could also have:
Just worked, until it randomly doesn't
mixed the output up even worse, like 1 1 2 3 | 3 4 5 7 | 5 6 9 | 7 8 | 9 10 |
put evenOddThread output above oddThread (probably unlikely but there is no guarantuee for how the threads get scheduled)

How can I find the stop and start index for a Java vector?

I have a vector that looks like this:
y =
Columns 1 through 19:
1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2
Columns 20 through 38:
2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 4 4 4 4
Columns 39 through 57:
4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 5 6
Columns 58 through 67:
6 6 6 6 6 6 6 6 6 6
The vector y is always start at 1 and be counted up. You see that there are lots of same numbers. It's the classes for the samples.
Here we have 1 1 1 1 1 1 1 1 1 1 1 1 = 12 samples for class number 1.
We have 2 2 2 2 2 2 2 2 2 2 2 = 11 samples for class number 2.
My problem here is that I want to find start and stop for every class. For example: Class 1 begins always at index 0 and ends, in this case, at index 11.
Class 2 begins directly after class 1 ends.
Question:
I'm using EJML (Effient Java Matrix Library) and I'm planning to use this function:
C = A.extractMatrix(1,4,2,8)
Which is equal to this MATLAB code:
C = A(2:4,3:8)
But I need to find the start and stop indexes from this y vector. In what index does e.g class 3 stops and starts? Do you have any smart ideas how to do that?
Sure, I could use a for-loop, to do this, but for-loops in Java is quite slow because I'm going to have a very very large y vector.
Suggestions?
Edit:
Here is an suggestion. Is that good, or could it be done better?
private void startStopIndex(SimpleMatrix y, int c, Integer[] startStop) {
int column = y.numCols();
startStop[0] = startStop[1] + 1; // Begin at the next class
for(int i = startStop[0]; i < column; i++) {
if(y.get(i) != c) {
break;
}else {
startStop[1] = i;
}
}
}
Assuming that we are calling the method from:
Integer[] startStop = new Integer[2];
for(int i = 0; i < c; i++) {
startStopIndex(y, c, startStop);
}
If you want to do it faster then binary search is your friend. Threw this together really quick and it does things in O(log n) time, where as a linear search does it in O(n). It's pretty basic and assumes your data looks pretty much like you describe it. Feed it weird data and it will break.:
int[] breakPoints(int[] arr, int low, int high){
int[] rtrn = new int[high];
for(int i=low;i<high;i++){
rtrn[i]=binarySearch(arr, i, 0, arr.length-1);
}
return rtrn;
}
int binarySearch(int[] arr, int k, int start, int end){
int mid = (start+end)/2;
if(mid==arr.length){
return -1;
}
if(arr[mid]==k && arr[mid+1]==k+1){
return mid+1; //or just mid if you want before breakpoint
}
if(arr[mid]<=k){
return binarySearch(arr, k, mid+1, end);
}
return binarySearch(arr, k, start, mid-1);
}
You'd call it like this:
int[] data = {1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,5,5,6,6,6,6};
int[] bp = breakPoints(data,1,6);
//return 0, 3, 8, 13, 16, 18
I think there is a name for this, but I can't remember what it might be, but you start looking for the next boundary with an accelerating search, and use a binary search after that.
You know the numbers are in ascending order, and there are potentially a lot of the same number, so you start by checking the next element. But instead of keep going 1 step at a time, you accelerate and step 2, 4, 8, 16, ... until you find a higher number.
Once you've found a higher number, you've gone too far, but the last step had the initial number, so you know the boundary is somewhere between the last two steps, and you then apply a binary search for the boundary.
Once you've fund the boundary, you start over stepping 1, 2, 4, ... for the next boundary.
If you expect most numbers to have about the same number of occurrences, you could keep a running average count, and make the first step with that average, to get a running start.
I'll leave it to you to actually code this.
The below is in MATLAB. the for loop will go through each unique value stored in x1 and then find the first and last occurrence of that value.
x = [ 1 1 1 2 2 3 3 3 3 3 4 4 4 4 5 5 5 ]
x1 = unique(x)'
for k1 = 1:length(x1)
x1(k1,2:3) = [find(x == x1(k1,1),1,"first"), find(x == x1(k1,1),1,"last")];
end
the above code yields x1 to be a 3 column matrix
1 1 3
2 4 5
3 6 10
4 11 14
5 15 17

Integer powers program Java help needed

So i was getting this program in my book and tested it, it worked fine. I need help though understanding how it excactly works. I know the power of two means for example 2x2x2x2x2x2x2x2x2 = 512. Well, here is the program:
// Compute integer powers of 2.
class Power {
public static void main(String args[]) {
int e;
int result;
for(int i=0; i < 10; i++) {
result = 1;
e = i;
while(e > 0) {
result *= 2;
e--;
}
System.out.println("2 to the " + i + " power is " + result);
}
}
}
So i've learned that result *=2 means: result = result * 2. I don't get how this works. Example, i is now 4. Result = 1 again, e=i, so e is now 4. 4 is higher than 0, so the while loop runs. Then it say's result is result * 2, but that's 1=1 * 2 = 2. But the result should be 16. How does result changes here to 16? Because it is 1 all the time. I don't get it. Also, why the e-- part? I've tried the program with e++, but then it prints result as 1 and after this only 0. Also tried it without e-- or e++ at all, but then it freezes in the dos-prompt. Please note that i am a beginner and this is my first while loop. Any help i would appreciate.
while(e > 0) {
result * = 2;
e--;
}
this loop executes untill the e becomes zero.
so in first loop
result = 1 * 2;
in second loop
result = result * 2; means result = 2 * 2
likewise.
You are using nested loops. That is, a while loop inside a for loop. This means that for every iteration of for loop, while loop will execute until it's condition becomes false.
Now coming to your questions, for first iteration of for, i = 0. Which means that e = 0, which in-turn means that while loop will not execute. So, result is 1 here, which is logical since any n^0 = 1.
For second iteration of for, i = 1. Which means that e = 1. Here, while loop will run for 1 iteration. It will make result = 2 (result *= 2). So, result is 2 because 2^1 = 2.
Below is the dry-run table.
for i while e result
loop loop
1 0 1 0 1
2 1 1 1 2
3 2 1 2 2
1 2 1 4
4 3 1 3 2
2 2 2 4
1 3 1 8
and so on. This table seems ugly, but it will give you a hint.
How does result changes here to 16? Because it is 1 all the time.
Result is only initialized with 1, but it's value is multiplied each time while loop executes.
I've tried the program with e++, but then it prints result as 1 and
after this only 0.
If you put e++ instead of e--, this loop will run until e overflows. But as soon value of e reaches 33, result will become 0 due to multiplication. And after that, it will remain 0.
Also tried it without e-- or e++ at all, but then it freezes in the
dos-prompt.
It means that your condition of while loop will never become false, and hence, it will be an infinite loop.

Task scheduling algorithm with individual deadline

I have n tasks, each has a specific deadline and time it takes to complete. However, I cannot complete all tasks with in their deadlines. I need to arrange these tasks in such a way to minimize the task's deadline over shoot time. Consider this case(left values are dead lines and right side values are time the task takes):
2 2
1 1
4 3
These three tasks can be done optimally like this:
time 1 : task 2 - task1 complete; 0 overshoot for task2
time 2 : task 1
time 3 : task 1 - task2 complete; 1 overshoot for task1
time 4 : task 3
time 5 : task 3
time 6 : task 3 - task3 complete; 3 overshoot for task3
I need a faster algorithm for this; my goal is to find maximum overshoot of all overshoots(in above case its 3). Right now, i am sorting the tasks based on deadlines but its not fast, as when a new task is added, I should sort the whole list. Is there any other way?
After Lawrey's suggestion, I am using PriorityQueue but it is not giving me exact sorting.
This is my code:
class Compare2DArray implements Comparator<int[]> {
public int compare(int a[], int b[]) {
for (int i = 0; i < a.length && i < b.length; i++)
if (a[i] != b[i])
return a[i] - b[i];
return a.length - b.length;
}
}
public class MyClass{
public static void main(String args[]) {
Scanner scan = new Scanner(System.in);
int numberOfInputs= scan.nextInt();
PriorityQueue<int[]> inputsList = new PriorityQueue<int[]>(numberOfInputs,new Compare2DArray());
for (int i = 0; i < numberOfInputs; i++) {
int[] input = new int[2];
input[0] = scan.nextInt();
input[1] = scan.nextInt();
inputsList.add(input);
}
}
But this is sorting this queue of arrays
2 2
1 1
4 3
10 1
2 1
as
1 1
2 1
4 3
10 1
2 2
instead of
1 1
2 1
2 2
4 3
10 1
The same comparator works fine over List sorting. I am not getting whats wrong with PriorityQueue
Priority Queue is implemented using heaps. Hence, when you scan over the elements of priority queue it will not guarantee that it will give you all elements in sorted order. That is why you are not getting the desired sorted array.
I also faced the same problem for the question. I ended up using multimap in c++. But still the time complexity didn't improved much.
Unless you have a really long list of tasks, e.g. millions, it shouldn't be taking that long.
However, what you need is likely to be a PriorityQueue which has O(1) add and O(ln N) take
I was attempting the same question (Its from interviewstreet, I suppose). Did you get this order:
1 1, 2 1, 4 3, 10 1, 2 2
when you printed the heap? Did you try popping items off the heap one by one and check their order?
I am saying this since my implementation is in python and when I print the heap, I get the same order as you were saying. But that is not the point here, I think, since when I pop elements of the heap, one by one, I get a proper order that is:
1 1, 2 1, 2 2, 4 3, 10 1
Here is what my code in python looks like: (I am using the heapq library for implementing the priority queue)
To add elements to the heap:
[deadline, minutes] = map( int, raw_input().split() )
heapq.heappush( heap, ( deadline, minutes ) )
To remove them from the heap:
d, m = heapq.heappop( heap )
Here is the output I get when I print the heap, followed by popping elements from the heap step by step:
Heap: [(1, 1), (2, 1), (4, 3), (10, 1), (2, 2)]
Job taken: 1 1
Job taken: 2 1
Job taken: 2 2
Job taken: 4 3
Job taken: 10 1
Hope that helps!

Categories