Print timed thread - java

I'm working on the following assignment:
Consider a shared counter whose values are non-negative integers,
initially zero. A time-printing thread increments the counter by one
and prints its value each second from the start of execution. A
message-printing thread prints a message every fifteen seconds. Have
the message-printing thread be notified by the time-printing thread as
each second passes by. Add another message-printing thread that prints
a different message every seven seconds. Such addition must be done
without modifying the time-printing thread implementation.
Have all involved threads share the counter object that is updated by
the time-printing thread every second. The time-printing thread will
notify other threads to read the counter object each time it updates
the counter, then each message-printing thread will read the counter
value and see if its assigned time period has elapsed; if so, it will
print its message.
import java.lang.Class;
import java.lang.Object;
public class Main2 {
public static void main(String... args)
{
Thread thread = new Thread()
{
public void run()
{
int x = 0;
while(true)
{
x = x + 1;
System.out.print(x + " ");
if(x%7 == 0)
{
System.out.println();
System.out.println("7 second message");
}
if(x%15 == 0)
{
System.out.println();
System.out.println("15 second message");
}
try { Thread.sleep(1000); }
catch (Exception e) { e.printStackTrace(); }
}
}
};
thread.start();
}
}
This outputs what I want it to, but the requirement calls for multiple threads to output when the 7 and 15 second messages show. I can't wrap my head around how to use multiple threads to do this.

You have to remove the ";" after if conditions.
if(x%7 == 0);
and
if(x%15 == 0);
Check the following code
public static void main(String... args) {
Thread thread = new Thread() {
public void run() {
int x = 0;
while (true) {
x = x + 1;
System.out.print(x + " ");
if (x % 7 == 0)
{
System.out.println();
System.out.println("7 second message");
}
if (x % 15 == 0)
{
System.out.println();
System.out.println("15 second message");
}
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
thread.start();
}
My output for this as follows
1 2 3 4 5 6 7
7 second message
8 9 10 11 12 13 14
7 second message
15
15 second message
16 17 18 19 20 21
7 second message
22 23 24 25 26 27 ...

Related

Java multithreading query

Hi I am a newbie in concurrent programming domain, I was testing the below code and seems the while loop is not terminating for threads. Could someone help explain whats happening here.
public class PrimePrinter{
public long counter = 0;
public synchronized long getCounter() {
return counter++;
}
public Thread makeThread() {
Runnable rn = new Runnable() {
/* (non-Javadoc)
* #see java.lang.Runnable#run()
*/
#Override
public void run() {
while (counter < 100) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " : " +getCounter());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
return new Thread(rn);
}
public static void main(String[] args) {
int n = 10;
Thread[] threads = new Thread[10];
PrimePrinter pp = new PrimePrinter();
for(int i = 1; i < n; i++) {
threads[i] = pp.makeThread();
threads[i].start();
}
}
}
Last few lines of output
Thread-4 : 81
Thread-5 : 87
Thread-7 : 91
Thread-5 : 97
Thread-2 : 95
Thread-4 : 98
Thread-6 : 96
Thread-8 : 90
Thread-1 : 93
Thread-3 : 92
Thread-0 : 94
Thread-2 : 99
Thread-6 : 107
Thread-3 : 103
Thread-0 : 104
Thread-1 : 105
Thread-8 : 106
Thread-5 : 102
Thread-4 : 101
Thread-7 : 100
This is not working for one reason that is crucial not to miss. Consider the way your code actually runs. It checks the counter value, then sleeps, THEN prints THEN increments.
You have 9 threads running at once. Then, 8 of these threads check the value, and at the time, the value is less than 100. So they pass the test and keep going. All 8 then sleep for 1000ms. Meanwhile, your other thread has just incremented the value... and 8 more are about to come out of their sleep.
So, if your value is 99 (which it inevitably will be), you'll now get a value of 100 from the thread that just incremented. Then, those 8 that already passed the test are also going to be incrementing, giving the counter a resulting value of 108.
However, the very last thread to run will show a value of 107 because you print THEN increment for all runs.
If you did this the other way around (like in the code below), you would not run into this problem.
The following code works correctly:
public class PrimePrinter {
public long counter = 0;
public synchronized long getCounter() {
return counter;
}
public synchronized void incrementCounter() {
counter++;
}
public Thread makeThread() {
Runnable rn = new Runnable() {
/*
* (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
#Override
public void run() {
while (getCounter() < 100) {
try {
incrementCounter();
System.out.println(Thread.currentThread().getName()
+ " : " + getCounter());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
return new Thread(rn);
}
public static void main(String[] args) {
int n = 10;
Thread[] threads = new Thread[10];
PrimePrinter pp = new PrimePrinter();
for (int i = 1; i < n; i++) {
threads[i] = pp.makeThread();
threads[i].start();
}
}
}
Each thread waits a second after having tested that counter < 100, during this second, other threads can increment the counter.
UPDATE: You could do something like this:
while (true) {
long current = getCounter();
if (current >= 100) {
break;
}
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " : " + current);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Incrementing variable multi-threading

Suppose I have 10 threads that are incrementing a variable by 1. Suppose Thread-1 increments a variable first, and then Thread-2 and Thread-3 and consecutively. after all the 10 Threads have incremented the variable. I need to decrement the same variable in a manner.
Decrementing, if Thread-1 incremented the variable first of all, then it should decrement at last.
We need to do this without setting thread priority.
you can use a lot of ways, here's one for example:
public class Main {
public static void main(String[] args) throws Exception {
for(int i=0;i<10;i++){
final int _i=i;
Thread t = new Thread(new T(_i));
t.start();
}
}
public static class T implements Runnable{
int threadNumber;
public T(int threadNumber) {
this.threadNumber=threadNumber;
}
#Override
public void run() {
increase(this);
}
}
static Thread[] threads = new Thread[10];
static int number =0;
static Object generalLock=new Object();
public static void increase(T t){
int myNumber=0;
synchronized (generalLock){
myNumber=number;
System.out.println("i am "+number+" incrementing, my real number "+t.threadNumber);
threads[number]=Thread.currentThread();
number++;
}
while (threads[9]==null){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for(int i=9;i>myNumber;i--){
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (generalLock){
System.out.println("i am "+number+" decrementing, my real number "+t.threadNumber);
number--;
}
}
}
output example:
i am 0 incrementing, my real number 1
i am 1 incrementing, my real number 8
i am 2 incrementing, my real number 9
i am 3 incrementing, my real number 7
i am 4 incrementing, my real number 6
i am 5 incrementing, my real number 5
i am 6 incrementing, my real number 0
i am 7 incrementing, my real number 4
i am 8 incrementing, my real number 3
i am 9 incrementing, my real number 2
i am 9 decrementing, my real number 2
i am 8 decrementing, my real number 3
i am 7 decrementing, my real number 4
i am 6 decrementing, my real number 0
i am 5 decrementing, my real number 5
i am 4 decrementing, my real number 6
i am 3 decrementing, my real number 7
i am 2 decrementing, my real number 9
i am 1 decrementing, my real number 8
i am 0 decrementing, my real number 1
Note: you can use simple Runnable, I create T class to show the thread number in order to print it while incrementing/decrementing
This seems to work. Essentially I create the 10 threads and specially identify one of them using an enum. They all try to increment the shared integer, identifying themselves. The incrementer detects the first increment by noticing the transition to 1 and if it's a Special thread it returns true .
There's also a CountDownLatch used to synchronise all of the threads to ensure there is at least a chance of the two alternatives. I get about 8600 out of the 10000 test runs where the Special got there first. This value will vary depending on many variables.
enum Who {
Special, Normal;
}
class PriorityIncrementer {
final AtomicInteger i = new AtomicInteger(0);
boolean inc(Who who) {
return i.incrementAndGet() == 1 && who == Who.Special;
}
public void dec() {
i.decrementAndGet();
}
}
class TestRunnable implements Runnable {
final Who me;
final PriorityIncrementer incrementer;
final CountDownLatch latch;
public TestRunnable(PriorityIncrementer incrementer, CountDownLatch latch, Who me) {
this.incrementer = incrementer;
this.latch = latch;
this.me = me;
}
#Override
public void run() {
// Wait for all others to get here.
latch.countDown();
try {
// Wait here until everyone os waiting here.
latch.await();
// Do it.
if(incrementer.inc(me)) {
// I was first and special, decrement after.
incrementer.dec();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private boolean test(int count) throws InterruptedException {
Thread[] threads = new Thread[count];
// The shared incrementer.
PriorityIncrementer incrementer = new PriorityIncrementer();
// Arrange for all of them to synchronise.
CountDownLatch latch = new CountDownLatch(threads.length+1);
// One special.
threads[0] = new Thread(new TestRunnable(incrementer, latch, Who.Special));
// The rest are normal.
for(int i = 1; i < threads.length; i++) {
threads[i] = new Thread(new TestRunnable(incrementer, latch, Who.Normal));
}
// Start them up.
for (Thread thread : threads) {
thread.start();
}
// Wait a moment.
Thread.sleep(1);
// Start them all going.
latch.countDown();
// Wait for them to finish.
for (Thread thread : threads) {
thread.join();
}
// Who won?
return incrementer.i.get() < count;
}
public void test() throws InterruptedException {
final int tests = 10000;
int specialWasFirstCount = 0;
for (int i = 0; i < tests; i++) {
if(test(10)) {
specialWasFirstCount += 1;
}
}
System.out.println("Specials: "+specialWasFirstCount+"/"+tests);
}

Finding prime number using BlockingQueue in Java with multi threading

I've implemented a multi thread program using BlockingQueue to test for a number is prime or not.
The requirement is the program will prompt user to input a number and then the program will print every prime number from 2 to inputted number from user in ascending order.
I have 3 class: NumberEnumerationTask for initialize BlockingQueue contains all numbers to be check, PrimeRunner for check the number is prime or not, PrimeChecker for the main class.
NumberEnumerationTask.java
package multithread;
import java.util.concurrent.BlockingQueue;
public class NumberEnumerationTask implements Runnable {
private BlockingQueue<Integer> queue;
private Integer maximum;
public static Integer DUMMY = new Integer(0);
public NumberEnumerationTask(BlockingQueue<Integer> queue, Integer maximum) {
this.queue = queue;
this.maximum = maximum;
}
#Override
public void run() {
try {
enumerate();
queue.put(DUMMY);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* Create a BlockingQueue contain Integer number from 1 to maximum.
* #throws InterruptedException
*/
private void enumerate() throws InterruptedException {
for (int i = 2; i < maximum; i++) {
queue.put(i);
}
}
}
PrimeRunner.java
package multithread;
import java.util.concurrent.BlockingQueue;
public class PrimeRunner implements Runnable {
private BlockingQueue<Integer> queue;
public PrimeRunner(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
boolean done = false;
while (!done) {
Integer checkNumber = queue.take();
if (checkNumber == NumberEnumerationTask.DUMMY) {
queue.put(checkNumber);
done = true;
} else {
checkPrimeNumber(checkNumber);
}
}
} catch(InterruptedException e) {
e.printStackTrace();
}
}
private void checkPrimeNumber(Integer number) {
boolean isPrime = true;
for (int i = 2; i <= number / 2; i++) {
if (number % i == 0) {
isPrime = false;
queue.remove(number);
break;
}
}
if (isPrime == true) {
System.out.print(number + " ");
queue.remove(number);
}
}
}
PrimeChecker.java
public class PrimeChecker {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter maximum number to check: ");
Integer number = sc.nextInt();
BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(number);
NumberEnumerationTask initialize = new NumberEnumerationTask(queue, number);
new Thread(initialize).start();
for (int i = 0; i <= number; i++) {
new Thread(new PrimeRunner(queue)).start();
}
sc.close();
}
}
The DUMMY variable is to signal completion.
When I run the program, sometime it's not print in ascending order, sometime it does.
Enter maximum number to check: 100
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Enter maximum number to check: 100
2 3 5 7 11 13 17 19 23 29 31 41 43 47 37 59 61 53 67 71 73 79 83 89 97
Can someone tell me what is wrong with my code? Thanks
In PrimeChecker, the following code is the cause:
for (int i = 0; i <= number; i++) {
new Thread(new PrimeRunner(queue)).start();
}
You create multiple PrimeRunner instances and a thread for each of them, so something like below can happen:
PrimeRunner in thread 1 takes 5.
PrimeRunner in thread 2 takes 7.
PrimeRunner in thread 2 prints 7. (PrimeRunner in thread 1 is still checking...)
PrimeRunner in thread 1 prints 5.
If you run a single PrimeRunner you can avoid such cases and it works as you expected.
If you still want to run multiple PrimeRunner surrounding the following part by synchronized block with an object in a static field of PrimeRunner should solve the problem:
Integer checkNumber = queue.take();
if (checkNumber == NumberEnumerationTask.DUMMY) {
queue.put(checkNumber);
done = true;
} else {
checkPrimeNumber(checkNumber);
}
Thread safety is the major issue. In your code, queue is shared among threads which is being processed without any synchronization mechanism hence data corruption likely to happen hence unpredictable result. If you run it multiple times you might get different results.
Multi-threading could be used for prime check to speed up the main goal i.e. prime finding which could be achieved by splitting the big number N into multiple parts and individual thread would work upon these parts and one thread to aggregate the results.

Multithreaded program - Threads cutting each other off

I am just testing out some threads, trying to figure out how to use them. My question is, how can I get my current scenario to work how I want it?
I want to have this program print out 1 - 100. I have two methods; oddNumbers and evenNumbers
oddNumbers:
public static void oddNumbers() {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) {
if (i % 2 == 1) {
System.out.println(i);
}
}
}
}).start();
}
evenNumbers:
public static void evenNumbers() {
new Thread(new Runnable() {
public void run() {
for (int q = 0; q < 100; q++) {
if (q % 2 == 0) {
System.out.println(q);
}
}
}
}).start();
}
main method
public static void main(String[] args) {
evenNumbers();
oddNumbers();
}
So, from what I understand, the methods oddNumbers and evenNumbers are running on different threads. So if they are, then why isn't my output 1-100?
Here's the output I get:
0
2
4
6
.
.
.
50
1
3
5
.
.
.
99
52
54
56
.
.
.
100
About half way through the evenNumbers loop, the oddNumbers loop cuts it off. Why does this happen, and how do I set it up so that it'll print 1-100?
Thanks in advance!
Because you did not tell threads to wait remaining participants.
It is hard to tell if next thread continues its work just after started or how long it will take to start. It could be several cpu cycles or 2 seconds.
You want exact instruction timing for realtime critical app? Start fpga programming.
For this java pc program, you could have used cyclic barrier just to let them do steps together without any starting priority importance.
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Demo {
public static CyclicBarrier barrier = new CyclicBarrier(2);
public static void oddNumbers() {
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) {
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (i % 2 == 1) {
System.out.println(i);
}
}
}
}).start();
}
public static void evenNumbers() {
new Thread(new Runnable() {
public void run() {
for (int q = 0; q < 100; q++) {
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (q % 2 == 0) {
System.out.println(q);
}
}
}
}).start();
}
public static void main(String[] args) {
evenNumbers();
oddNumbers();
}
}
barrier instance is created here with room for 2 threads so every 2 await action resets it and threads can wait on it again on next iteration.
Still, it has probability to output:
1
0
3
2
5
4
...
instead of
0
1
2
3
it could be solved using a third action to combine 2 threads results before printing to console.
The hardness here is you ask for serial action in a multithreaded environment.
I understand you don't want them to be alternated, just understand why each is executed for so long.
That decision is taken by the scheduler of the operating system. It decides when to switch to another thread. The thing with your example is that your threads are so small, they are executed so quickly.
The scheduler gives the power to be executed to a thread for some time, the problem is, that time is enough to display so many numbers of your loop, so they are not switched many times.
You would get better results if you had it running longer, use much bigger numbers. Or, you can also make the loops take longer before printing, add some calculus that takes time, so that it doesn't print that many numbers in a row.

I can't understand how examples with synchronized work

I just started learning "multithreading" in JAVA and it seams I don't understand how keyword "synchronized" works.
I had four examples and they're very alike (in my opinion), and I don't understand why I get every time different results.
public class BufferThread1 {
static int counter = 0;
static StringBuffer s = new StringBuffer();
public static void main(String args[]) throws InterruptedException {
new Thread() {
public void run() {
synchronized (s) {
while (BufferThread1.counter++ < 3) {
s.append("A");
System.out.print("> " + counter + " ");
System.out.println(s);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(BufferThread1.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}.start();
Thread.sleep(100);
while (BufferThread1.counter++ < 6) {
System.out.print("< " + counter + " ");
s.append("B");
System.out.println(s);
}
}
}
Result:
run:
> 1 A
< 2 > 3 AA
AAB
< 5 AABB
< 6 AABBB
public class BufferThread2 {
static int counter = 0;
static StringBuilder s = new StringBuilder();
public static void main(String args[]) throws InterruptedException {
new Thread() {
public void run() {
synchronized (s) {
while (BufferThread2.counter++ < 3) {
s.append("A");
System.out.print("> " + counter + " ");
System.out.println(s);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(BufferThread2.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}.start();
Thread.sleep(100);
while (BufferThread2.counter++ < 6) {
System.out.print("< " + counter + " ");
s.append("B");
System.out.println(s);
}
}
}
Result:
run:
> 1 A
< 2 AB
< 3 ABB
< 4 ABBB
< 5 ABBBB
< 6 ABBBBB
public class BufferThread3 {
static int counter = 0;
static StringBuffer s = new StringBuffer();
public static void main(String args[]) throws InterruptedException {
new Thread() {
public void run() {
synchronized (s) {
while (BufferThread3.counter++ < 3) {
s.append("A");
System.out.print("> " + counter + " ");
System.out.println(s);
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
Logger.getLogger(BufferThread3.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}.start();
Thread.sleep(100);
synchronized (s) {
while (BufferThread3.counter++ < 6) {
System.out.print("< " + counter + " ");
s.append("B");
System.out.println(s);
}
}}
}
Result:
run:
> 1 A
> 2 AA
> 3 AAA
< 5 AAAB
< 6 AAABB
Of course, I skipped
import java.util.logging.Level;
import java.util.logging.Logger;
I just don't realise how these examples work and synchronized here !
I do hope that someone help me.
Your < and > label which thread is running here.
> 1 A
Your background thread is running only and prints this line as expected.
< 2
The main thread prints the counter 2 but cannot acquire the lock on s so it blocks.
> 3 AA
The background thread increments the counter again and prints 3 and a second A. On the next iteration it exits and counter == 4 As the thread exits, it releases the lock.
AAB
The main thread can now acquire the lock and append("B")
< 5 AABB
The main thread increments the counter to 5 and adds another B
StringBuffer is a pet hate of mine which was replaced more thna ten years ago by StringBuidler. It is almost impossible to implement a useful thread safe class using it and when people have tried, it has meant the class wasn't really thread safe. Note: SimpleDateFormat uses StringBuffer and it is not thread safe.
Let's try a simpler example that gets at what synchronized does without such an overly complicated class.
Consider the following Runnable task:
public class Task implements Runnable {
private final int id;
public Task(int id) {
this.id = id;
}
public void run() {
for(int i = 0; i < 5; i++) {
System.out.println("Task " + id + " prints " + i);
}
}
}
Then let's try running it with this main method:
public static void main(String[] args) {
Thread t1 = new Thread(new Task(1));
Thread t2 = new Thread(new Task(2));
t1.start();
t2.start();
}
The output could look something like this:
Task 1 prints 0
Task 1 prints 1
Task 1 prints 2
Task 1 prints 3
Task 1 prints 4
Task 2 prints 0
Task 2 prints 1
Task 2 prints 2
Task 2 prints 3
Task 2 prints 4
But it could also look like this:
Task 1 prints 0
Task 2 prints 0
Task 2 prints 1
Task 1 prints 1
Task 1 prints 2
Task 1 prints 3
Task 1 prints 4
Task 2 prints 2
Task 2 prints 3
Task 2 prints 4
Task 2 prints 4
The truth is, you have no guarantees about the order in which the two Tasks execute commands (with respect to each other. You still do know that each task will print 0...4 in order). The fact that t1.start() comes before t2.start() means nothing.
The synchronized command allows for some control over which thread executes when. Essentially, the command synchronized(obj) {....} means that at most one thread is allowed to execute the commands in the block (within the {...}) at a time. This is know as mutual exclusion.
A nice way to think about it is as a locked room with a single key hanging outside on the wall. In order to get into the room, you have to take the key off the wall, unlock the door, go into the room, and lock it from the inside. Once you are done doing whatever you are doing in the room, you unlock the door from the inside, go outside, lock the door from the outside, and hang the key up. It is clear that while you are in the room no one else can join you, as the door is locked and you currently hold the only key to get in.
To illustrate, consider the following improved task class:
public class SynchronizedTask implements Runnable {
private final Object lock;
private final int id;
public Task(int id, Object lock) {
this.id = id;
this.lock = lock;
}
public void run() {
synchronized(lock) {
for(int i = 0; i < 5; i++) {
System.out.println("Task " + id + " prints " + i);
}
}
}
}
And run it with the following modified main method:
public static void main(String[] args) {
Object lock = new Object();
Thread t1 = new Thread(new Task(1, lock));
Thread t2 = new Thread(new Task(2, lock));
t1.start();
t2.start();
}
We still don't know whether t1 or t2 will enter the synchronized block first. However, once has entered, the other must wait for it to finish. Thus, there are exactly two possible outputs of this code. Either t1 gets in first:
Task 1 prints 0
Task 1 prints 1
Task 1 prints 2
Task 1 prints 3
Task 1 prints 4
Task 2 prints 0
Task 2 prints 1
Task 2 prints 2
Task 2 prints 3
Task 2 prints 4
Or t2 gets in first:
Task 2 prints 0
Task 2 prints 1
Task 2 prints 2
Task 2 prints 3
Task 2 prints 4
Task 1 prints 0
Task 1 prints 1
Task 1 prints 2
Task 1 prints 3
Task 1 prints 4
It is important to note that this behavior only worked as desired because we used the same lock object for both Tasks. If we had run the following code instead:
public static void main(String[] args) {
Thread t1 = new Thread(new Task(1, new Object()));
Thread t2 = new Thread(new Task(2, new Object()));
t1.start();
t2.start();
}
We would have identical behavior to the original un-synchronized code. This is because we now have a room with two (or really, infinite if we replicate our thread initialization) keys hanging outside. Thus while t1 is inside the synchronized block, t2 can just use its own key to get in, defeating the whole purpose.
First example shown by Mr. Lawrey.
In the second example the "Background" thread only gets to do one print of and since StringBuilder is used this time instead of StringBuffer the main thread will not block while trying to print "s", hence only 1 A.
In the third example the main thread is blocked until the background thread terminates because you start the background thread before the main thread's loop. Thus the background thread will get 3 loops done and hence the 3 A's.
Though I suspect these are artificial examples for learning purposes it should still be noted that sleeping inside a synchronized block is NOT a good idea as this will not release the lock.

Categories