Why my synchronized method not working properly? - java

I have this synchronized method that prints counter, I have 4 Threads so I am expecting final value of my counter to be 400000 as my counter is a static variable.
but every time I run my code, it is giving me different values of counter.
Following is my code:
class MyThread implements Runnable{
private static int counter=1;
#Override
public void run() {
try {
this.syncMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void syncMethod() throws InterruptedException{
for(int i=0;i<100000;i++){
System.out.println(Thread.currentThread().getName()+" : "+counter++);
}
}
}
public class MyController {
public static void main(String[] args) throws InterruptedException {
Runnable r1=new MyThread();
Runnable r2=new MyThread();
Runnable r3=new MyThread();
Runnable r4=new MyThread();
Thread t1;
Thread t2;
Thread t3;
Thread t4;
t1=new Thread(r1,"Thread 1");
t2=new Thread(r2,"Thread 2");
t3=new Thread(r3,"Thread 3");
t4=new Thread(r4,"Thread 4");
t2.start();
t1.start();
t3.start();
t4.start();
}
}

The variable is static, but the method that you synchronized is not static. This means that it will acquire the monitor on the current instance, and every thread has a different current instance.
A simple solution is to make the syncMethod method static as well; in that case, it will take a lock on the monitor that is shared by all instances of the MyThread class:
public static synchronized void syncMethod()

Erwin Bolwidt's answer is right to solve your problem. As another way to increment a static shared counter in multiple threads safely, you can turn to AtomicLong.
Define it as this:
private static AtomicLong counter = new AtomicLong();
Increment it as:
counter.getAndIncrement();
And in the end, get the result:
counter.get();

synchronised key word in non static methods means exactly synchronize me for this methods : this two code a striclty equivalent :
public synchronised void dojob(){
//the job to do
}
et
public void dojob(){
synchronised (this){
//the job to do
}
}
in your case your synchronized methods are synchronizing on different object (t1,t2,t3 and t4) so didn't block them each other . the best solution is thaat your thread will use a common object to synchronized each other. an other point it alway better to get its thread back to do this call join here is a code to do what you want with this 2 fixes
class MyThread implements Runnable {
public static class JobDoer {
public synchronized void syncMethod() throws InterruptedException {
for (int i = 0; i < 100000; i++) {
System.out.println(Thread.currentThread().getName() + " : " + counter++);
}
}
}
private static int counter = 1;
public MyThread(JobDoer doer) {
this.doer = doer;
}
private JobDoer doer;
#Override
public void run() {
try {
doer.syncMethod();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
JobDoer doer = new JobDoer();
Thread t1 = new Thread(new MyThread(doer), "Thread 1");
Thread t2 = new Thread(new MyThread(doer), "Thread 2");
Thread t3 = new Thread(new MyThread(doer), "Thread 3");
Thread t4 = new Thread(new MyThread(doer), "Thread 4");
t2.start();
t1.start();
t3.start();
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();
}
}

Related

How wait() and notifyAll() prevents deadlock in given code snippet?

Here is the code snippet:
public class PrintEvenOdd
public static class SynchronizedThreadMonitor {
public final static boolean ODD_TURN = true;
public final static boolean EVEN_TURN = false;
private boolean turn = ODD_TURN;
public synchronized void waitTurn(boolean oldTurn) {
while (turn != oldTurn) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("InterruptedException in wait(): " + e);
}
}
}
public synchronized void toggleTurn(){
turn ^= true;
notify();
}
}
public static class OddThread extends Thread {
private final SynchronizedThreadMonitor monitor;
public OddThread(SynchronizedThreadMonitor monitor) {
this.monitor = monitor;
}
#Override
public void run() {
for (int i=1; i<=100; i+=2) {
monitor.waitTurn(SynchronizedThreadMonitor.ODD_TURN);
System.out.println("i= " + i);
monitor.toggleTurn();
}
}
}
public static class EvenThread extends Thread {
private final SynchronizedThreadMonitor monitor;
public EvenThread(SynchronizedThreadMonitor monitor) {
this.monitor = monitor;
}
#Override
public void run() {
for (int i=2; i<=100; i+=2) {
monitor.waitTurn(SynchronizedThreadMonitor.EVEN_TURN);
System.out.println("i= " + i);
monitor.toggleTurn();
}
}
}
public static void main(String[] args) throws InterruptedException {
SynchronizedThreadMonitor monitor = new SynchronizedThreadMonitor();
Thread t1 = new OddThread(monitor);
Thread t2 = new EvenThread(monitor);
t1.start();
t2.start();
t1.join();
t2.join();
}
}
Using 2 threads to print numbers. One prints odd numbers and another prints even numbers.
In my understanding, both waitTurn and toggleTurn share the same LOCK of the instance. So if one holds the LOCK, the other method could not run. So if EvenThread first invokes waitTurn method and wait for the turn change, it holds the LOCK, then OddThread could not enter the toggleTurn method and set the turn. This should lead to a deadlock as per my understanding. But it did not happen.
Can someone please explain why the deadlock did not happen?
"So IF EvenThread first run waitTurn method and wait for the turn change, it holds the LOCK, the OddThread could NOT enter the toggleTurn method"
It holds the LOCK only small period of time, until method wait() is invoked. Method wait() releases the LOCK and allows another thread to enter the critical section.

Why synchronized block is giving wrong answer?

I am trying to learn synchronization. Got stuck here according to what I have learned the following code should give 8000 as the final result but I am getting a random result like below
package threads;
import java.time.LocalDateTime;
public class A implements Runnable {
String name;
static Integer j=0;
A(String name){
this.name=name;
}
#Override
public synchronized void run() {
for(int i=1;i<=1000;i++){
synchronized(this){
A.j++;
}
}
System.out.println(j);
}
package threads;
public class MainClass {
public static void main(String args[]){
Thread t1=new Thread(new A("i am thread A "));
Thread t2=new Thread(new A("i am thread B "));
Thread t3=new Thread(new A("i am thread C "));
Thread t4=new Thread(new A("i am thread D "));
Thread t5=new Thread(new A("i am thread E "));
Thread t6=new Thread(new A("i am thread F "));
Thread t7=new Thread(new A("i am thread G "));
Thread t8=new Thread(new A("i am thread H "));
t1.setPriority(Thread.MAX_PRIORITY);
t8.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
still getting output like 1293
2214
1403
3214
4214
5214
6224
7037
can anyone explain to me how to achieve synchronization and what is going wrong here?
It is a common mistake to think that synchronized means "critical section", and that no other threads will run while a synchronized block is running. But synchronized blocks are only exclusive with respect to other synchronized blocks that lock on the same lock.
The answers you got ("use a common lock") are right, but didn't really tell you why. The other common mistake is to think about synchronized as protecting code, when really you should be thinking about it protecting data. Any shared mutable data should be guarded by one and only one lock, and you should know exactly what that lock is. (The more complex your locking scheme, the less likely you'll know what locks guard what data.) So you should always be thinking in terms of "data X is guarded by lock L", and then make sure you acquire lock L whenever you access (read or write) that data.
This will solve the issue. You have to synchronize using a shared lock to all the threads since you are incrementing a static field. Otherwise each object will have it's own lock and increment the static field in parallel leading to a race condition. That's why you are not getting correct value which is 8000 in this case.
package bookmarks;
public class A implements Runnable {
String name;
static Integer j = 0;
private static Object lock = new Object();
A(String name) {
this.name = name;
}
#Override
public void run() {
for (int i = 1; i <= 1000; i++) {
synchronized (lock) {
A.j++;
}
}
System.out.println(j);
}
}
There are a couple of issues in the code.
Issue 1: Lock object added in synchronized(..) is not shared among
all thread instances
Issue 2: System.out.println(j); line should be in the end after t8.join(); otherwise, you will be given 8 times output.
The rectified code
public class A implements Runnable {
String name;
static Integer j = 0;
static Object lockObject = new Object();
A(String name) {
this.name = name;
}
#Override
public void run() {
for (int i = 1; i <= 1000; i++) {
synchronized (lockObject) {
A.j++;
}
}
}
public static void main(String args[]) {
Thread t1 = new Thread(new A("i am thread A "));
Thread t2 = new Thread(new A("i am thread B "));
Thread t3 = new Thread(new A("i am thread C "));
Thread t4 = new Thread(new A("i am thread D "));
Thread t5 = new Thread(new A("i am thread E "));
Thread t6 = new Thread(new A("i am thread F "));
Thread t7 = new Thread(new A("i am thread G "));
Thread t8 = new Thread(new A("i am thread H "));
t1.setPriority(Thread.MAX_PRIORITY);
t8.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(A.j);
}
}

How can I call a same method with three different thread

Suppose I have a method called Magic() I want to execute this method with three different thread.
I know how to execute Magic() method with a single thread, but I am confuse, How do I do with three different threads?
Suppose I have a method called Magic() I want to execute this method with three different thread
Create a MagicTask class that represents the task that each Thread will execute and call the magic() method inside run() :
class MagicTask implements Runnable {
public void run() {
magic();
}
public void magic() { //do magic }
}
Then create three threads and pass it the task :
Thread t1 = new Thread(new MagicTask());
Thread t2 = new Thread(new MagicTask());
Thread t3 = new Thread(new MagicTask());
Then start the threads :
t1.start();
t2.start();
t3.start();
Note You can pass the same MagicTask instance to all three Thread instances as well. Remember that if MagicTask has state that can get inconsistent when accessed by different threads, you also need to make your class thread-safe by using intrinsic locking using synchronized or other such constructs which are out of the scope for this answer.
class Multi3 implements Runnable{
public void run(){
System.out.println("thread is running...");
call();
}
void call(){
System.out.println("method call by"+Thread.currentThread().getName());
}
public static void main(String args[]){
Multi3 m1=new Multi3();
Thread t1 =new Thread(m1);
Thread t2 =new Thread(m1);
Thread t3 =new Thread(m1);
t1.start();
t2.start();
t3.start();
}
}
Here Thread t1,t2,t3 are calling the same method call().
If you are using Java 8, function references are straightforward:
public class Main {
public static void magic() {
System.out.println("this is magic");
}
public static void main(final String args[]) {
new Thread(Main::magic).start();
new Thread(Main::magic).start();
new Thread(Main::magic).start();
}
}
And if magic isn't a static method use:
public class Main {
public void magic() {
System.out.println("this is magic");
}
public static void main(final String args[]) {
Main m = new Main();
new Thread(m::magic).start();
new Thread(m::magic).start();
new Thread(m::magic).start();
}
}
You can try Like.
I am dividing the task to different thread
Try your own logic it just a simple even count,
public class CountNumber implements Runnable {
int stop;
int start;
int totalEvenNo;
public CountNumber(int start, int stop)
{
this.start=start;
this.stop=stop;
}
public void run()
{
int total= countEven(start, stop);
System.out.println("Total Even numbers are :"+total);
}
public int countEven(int str,int stp)
{
for(int i=str;i<=stp;i++)
{
if(i%2==0)
{
totalEvenNo +=1;
System.out.println(totalEvenNo);
}
}
return totalEvenNo;
}
}
public class MainClassNumber {
public static void main(String[] args) {
System.out.println("Spawaning Thread.........");
Thread t1 = new Thread(new CountNumber(0, 500000));
Thread t2 = new Thread(new CountNumber(500001, 2000000));
Thread t3 = new Thread(new CountNumber(2000001, 5000000));
Thread t4 = new Thread(new CountNumber(5000001, 10000000));
Thread t5 = new Thread(new CountNumber(10000001, 20000000));
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
Call it directly like magic(); And for better result synchronize that method like below
public synchronized void magic(){
//your code
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable {
public void run() {
Magic();
}
private void Magic() {
// consider synchronizing this method, but if you do method will be accessable by one thread at a time.
}
}
public class TestThreadPool {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3)
for (int i = 0; i < 3; i++) {
Runnable worker = new WorkerThread();
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {}
}
}
}

wait for N-1 out of N threads to end, then issue an instruction for the last thread

So, i apologize for the title. It's quite hard to explain in one sentence what i would like to do if you have no idea on how it is called.
So assume i can only use primitive thread functions (wait, notify, no concurrent package)
The program has 3 threads, all of them are the same and are called by the main thread. They behave normally until one of the three get an exception and so it must wait for the end of the remaining 2 threads in order to start a recovery process.
I was thinking about a static variable but I'm not really sure about it, i would love to keep it as simple as possible.
Each thread starts at the same time.
I don't see any reason why you can't use a static variable like you suggest. Here's how I would do it with an inner class...
private static boolean running = true;
public void test26546397() {
while (true) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
running = true;
// Do recovery
}
}
public class MyRunnable implements Runnable {
#Override
public void run() {
while (running) {
try {
// doStuff
} catch (Exception ex) {
running = false;
}
}
}
}
I would of course replace the while (true) with something a little more suitable.
I think you need java.concurrent.CountdownLatch, however if the java.concurrent package is not available to you can code this yourself using Object.wait/notify and synchronized blocks.
The latch can then be decremented in a finally {} on each Thread, this will be run if the Thread completes, or an exception occurs.
Your main program then just needs to wait for count to become 0.
public class StackOverflow26546397 {
static class CountdownLatch {
private int count;
private Object monitor = new Object();
public CountdownLatch(int count) {
this.count = count;
}
public void countDown() {
synchronized (monitor) {
count--;
monitor.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (monitor) {
while (count > 0) {
monitor.wait();
}
}
}
}
static class Job implements Runnable {
private CountdownLatch latch;
public Job(CountdownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
try {
// do work.
Thread.sleep((long) (Math.random() * 3000d));
} catch (InterruptedException e) {
//
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) throws InterruptedException {
CountdownLatch latch = new CountdownLatch(3);
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
latch.await();
System.out.println("All threads finished");
}
}
Not sure what you are trying to do but this is as simple as I can think of (just native concurrency):
Create a static or shared volatile boolean
private static volatile boolean exceptionOccured=false
Set the above to 'true' when exception occurs:
....}catch(Exception e){
exceptionOccured=true;
}
Check this periodically in you normal thread flow:
if (exceptionOccured)
//enter you synchronized call here
the synchronized method could look something like:
public synchronized void checkAndRecover(){
//decrement a counter or other logic to identify which is the last Thread and then
//perform any recovery logic
}

synchronized increment an int value

Why this program doesn`t display 2000 at every execution? I know that I can use AtomicInteger, but I am curious.
class Increment extends Thread{
static Integer i=new Integer(0);
public void run(){
for(int j=1;j<=1000;j++){
synchronized (i) {
i++;
}
}
}
}
public class Puzzle {
public static void main(String args[]) {
Thread t1=new Increment();
Thread t2=new Increment();
t1.start();
t2.start();
try {
t1.join();
t2.join();
}catch (InterruptedException r){}
System.out.println(Increment.i);
}
}
You synchronize on a mutable variable i. This variable changes its value each time, therefore each time you acquire a lock on another object. Each thread thus acquires a non-contended lock and can proceed simultaneously, as if no synchronization was in place.
Lesson: use a dedicated private static final Object lock = new Object() as a lock.

Categories