Reputation: 79
So i hava a thread that replaces the smallest char in an array of chars with another, random char. The thread runs until the array consists only of 'z'. But when i create multiple threads i get weird outputs and im wondering wether its only problem with printing or if my code is actually incorect.
run()
method in my thread:
public void run() {
char[] expected = { 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z' };
while (timesModified < 100 && !Arrays.equals(array, expected)) {
try {
array[findMinIndex(array)] = rndChar();
timesModified++;
Thread.sleep(2000);
for (char c : array) {
System.out.print(c + " ");
}
System.out.println();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
My main:
public static void main(String[] args) {
char[] sa_table = new char[10];
Arrays.fill(sa_table, 'a');
Thread t = new Thread(new AddToTable(sa_table));
Thread t1 = new Thread(new AddToTable(sa_table));
Thread t2 = new Thread(new AddToTable(sa_table));
t.start();
t1.start();
t2.start();
try {
t.join();
t1.join();
t2.join();
} catch (Exception e) {
System.out.println("Interrupted");
}
}
Output from console:
n n n a a a a a a a a a a a a a a a a a a a a a
a a a a a a
n u U a n u U a a a a a a a
a a a a a a
n u N a a a a a a a
n n u o a a a a a a a
u o K a a a a a a
n u o i a a a a a a
n u o i A a a a a a
n u o i A a a a a a
n u o i G a a a a a
n u o i K a a a a a
n u o i u a a a a a
n u o i u s a a a a
n u o i u s x a a a
n n n u o i u s u o i u s x l a a
u o i u s x l D a
x l h a
n u o i u s x l h H
n u o i u s x l h D
n u o i u s x l h a
n u o i u s x l h r
n u o i u s x l R r
n u o i u s x l v r
n u o C u s x l v r
n u o b u s x l v r
n n u o S u s x l v r
u o D u s x l v r
n u o T u s x l v r
n u o l u s x l v r
n u o M u s x l v r
n u o M u s x l v r
n u o t u s x l v r
n u o t u s x m v r
n u o t u s x J v r
n u o t u s x R v r
n u o t u s x i v r
n u o t u s x t v r
F u o t u s x t v r
A u o t u s x t v r
D u o t u s x t v r
l u o t u s x t v r
e u o t u s x t v r
L u o t u s x t v r
L u o t u s x t v r
o u o t u s x t v r
m u o t u s x t v r
s u o t u s x t v r
s u C t u s x t v r
s u D t u s x t v r
s u q t u s x t v r
s u W t u s x t v r
s u Y t u s x t v r
s u C t u s x t v r
s u s t u s x t v r
s u s t u s x t v h
s u s t u s x t v D
s u s t u s x t v w
I u s t u s x t v w
c u s t u s x t v w
g u s t u s x t v w
b u s t u s x t v w
N u s t u s x t v w
O u s t u s x t v w
u u s t u s x t v w
u u E t u s x t v w
u u u u C t u s x t v w
u T u T t u s x t v w
t u s x t v w
u u u X t u s x t v w u X t u s x t v w
u u D t u s x t v w
u u u T t u s x t v w
u u X t u s x t v w
u e t u s x t v w
u u f t u s x t v w
u u C t u s x t v w
u u u t u s x t v w
u u u t u o x t v w
u u u t u i x t v w
u u u t u P x t v w
u u u t u v x t v w
u u u b u v x t v w
u u u u u u K u v x t v w
u u u x u v x t v w
x u v x K v w
u u u x u v x W v w
u u u x u v x c v w
u u u u u x u v x e v w
u u u u x u v x n v w
u u u x u v x q v w
x u v x T v w
u u u x u v x w v w
z u u x u v x w v w
z P u x u v x w v w
z T u x u v x w v w
z z b u x u v x w v w b u x u v x w v w
z p u x u v x z p u x u v x w v w
w v w
As you can see, the output often has different lenght and i'm not sure what causes it
Upvotes: 0
Views: 434
Reputation: 60
Without looking into the code to check if it does the actual task correctly, the answer to the varying length is simple: Three threads print out values concurrently, so you do not know which thread printed out which value.
For example, these lines:
u u u u C t u s x t v w
u T u T t u s x t v w
t u s x t v w
were printed by three threads. That's why the total number of values is correct, and so is the number of line breaks (3). Try printing in a way that includes the thread id with each value, and you'll see you did not get one line per thread each time, but a mixture of values and line breaks from each of the participating threads.
To avoid this, you may use a StringBuilder to assemble each thread's values and then print them out in one go.
Try this:
public void run() {
char[] expected = { 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z', 'z' };
while (timesModified < 100 && !Arrays.equals(array, expected)) {
try {
array[findMinIndex(array)] = rndChar();
timesModified++;
Thread.sleep(2000);
StringBuilder sb = new StringBuilder();
for (char c : array) {
sb.append(c + " ");
}
System.out.println(sb);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Upvotes: 0
Reputation: 1656
Your problem comes from here:
for (char c : array) {
System.out.print(c + " ");
}
System.out.println();
This loop can be paused while in the middle in one thread and start in another, so you have the printing of two threads that mix before you call the println()
.
For example, when you have:
n n u o S u s x l v r
u o D u s x l v r
It means that you had this String: n u o S u s x l v r
, and one thread started printing it, it printed the n
, then another took over, printed everything -> n n u o S u s x l v r
+ a \n
(println()
), then the first one ended what he was doing, and printed the rest: u o D u s x l v r
.
Upvotes: 2
Reputation: 336
It seems like you are facing the "Mutal exclusion" or "Mutex" problem here:
https://en.wikipedia.org/wiki/Mutual_exclusion
You have to make sure that the array is not edited by multilple threads at the same time.
Upvotes: 0