Multithreading - Synchronizing the block for all instances of an Object - java

I have a class as Calculate. I created two threads both working on different instances of this class and tried to get the value of i. But both are giving me same values.
I want if one thread of a instance is working then the thread working on other instance should wait.
public class Calculate {
private int i=2;
public void showNumber(){
synchronized(Calculate.class){
i=i+2;
}
System.out.println(Thread.currentThread()+"Value of i is "+i);
}
}
class Test1 implements Runnable{
Calculate c=null;
public Test1(Calculate c){
this.c=c;
}
#Override
public void run() {
System.out.println(Thread.currentThread()+" Running");
c.showNumber();
}
}
public class ThreadingPractise {
public static void main(String[] args) {
Calculate c=new Calculate();
Calculate c1=new Calculate();
Thread t1=new Thread(new Test1(c),"t1");
Thread t2=new Thread(new Test1(c1),"t2");
t1.start();
t2.start();
}
}

make i as static. If you want to share the variable between threads. and synchronize showNumber method instead of Calculate.class so that only 1 thread will run it at a time.

Related

java synchronized fails to synchronize

How do I synchronize the run method?
If I use the synchronized keyword here, it doesn't work. It gives me a different output every time?
class MyClass implements Runnable
{
boolean flag;
public MyClass(boolean val)
{
flag=val;
}
public synchronized void run()
{
long id=Thread.currentThread().getId();
int start=(flag)?1:2;
for(int i=start;i<=10;i+=2)
{
System.out.println("Thead "+id+" prints:"+i);
}
}
}
public class Main {
public static void main(String[] args)
{
Thread t1=new Thread(new MyClass(false));
t1.start();
Thread t2=new Thread(new MyClass(true));
t2.start();
}
}
Each thread is using a different instance of MyClass. If you use synchronized on a non static instance, this ensure the method is not executed by several threads at the same for the same MyClass instance. If you want to synchronize for all instances of MyClass, the method has to be static.
class MyClass implements Runnable {
boolean flag;
public MyClass(boolean val)
{
flag=val;
}
private static synchronized void runTask(boolean flag) {
long id=Thread.currentThread().getId();
int start=(flag)?1:2;
for(int i=start;i<=10;i+=2)
{
System.out.println("Thead "+id+" prints:"+i);
}
}
public void run()
{
runTask(flag);
}
}

Why the following code of multithreading is not working? The answer should be 20000 I believe

Why am I not getting 20000 when the increment method is synchronized. I did the same thing with runnable and it worked.
public class ThreadClass extends Thread
{
static int count=0;
public synchronized void increment()
{
count++;
}
public void run()
{
for(int i=0;i<10000;i++)
{
increment();
}
};
}
public class Main {
public static void main(String[] args) {
ThreadClass t1=new ThreadClass();
ThreadClass t2= new ThreadClass();
t1.start();
t2.start();
try {
t2.join();
t1.join();
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println(ThreadClass.count);
}
}
The JLS, for synchronized methods, clearly states the following:
For an instance method, the monitor associated with this (the object for which the method was invoked) is used.
As a result, the two ThreadClass instances will lock independently, and there will be no common lock protecting bad writes to count.
Synchronize explicitly on Threadclass.class or make increment() static to actually synchronize in a manner that makes writes safe.

Defining two different Threads in java

Im new to Threads and I was wondering how could I define what two or more different Threads do in a Java program. Do i define them all in the same public void run method? If so, how do I do it? I would like the Threat t1 to invoke the increment method, t2 to invoke the decrement method and both of them to call the value method
Here's the code example:
package interference;
/**
*
* #author rodrigopeniche
*/
public class Interference implements Runnable{
/**
* #param args the command line arguments
*
*/
Counter counter1= new Counter();
class Counter{
private int c= 0;
public void increment()
{
c++;
}
public void decrement()
{
c--;
}
public int value()
{
return c;
}
}
public static void main(String[] args) {
// TODO code application logic here
Thread t1= new Thread(new Interference());
Thread t2= new Thread(new Interference());
t1.start();
t2.start();
}
#Override
public void run() {
counter1.increment();
counter1.decrement();
counter1.value();
}
}
You can set names to threads like thread1, thread2. After that, in the run method, check the name of the thread currently running and do the necessary action.
You have to add a while loop inside the run method if you need to run it longer.
public static void main(String[] args) {
Interference interference = new Interference();//create a new Interference object
Thread t1 = new Thread(interference, "thread1");//pass the runnable interference object and set the thread name
Thread t2 = new Thread(interference, "thread2");//pass the runnable interference object and set the thread name
t1.start();
t2.start();
}
#Override
public void run() {
while (true) {//to run it forever to make the difference more visual
String threadName = Thread.currentThread().getName();//get the current thread's name
if (threadName.equals("thread1")) {//if current thread is thread1, increment
counter1.increment();
} else if (threadName.equals("thread2")) {//if current thread is thread2, decrement
counter1.decrement();
}
System.out.println(counter1.value());//print the value
}
}
When you run the code, you can see count is going up and down in a random manner.
In your current code, counter1 is an instance variable of class Interference. You create 2 instances of Interference and then use them to create two Thread objects. When the threads start to run, each Thread is actually working on it's own copy of counter1. I think that may not be what you expect.
package interference;
public class Interference {
static class Counter {
private int c = 0;
public void increment() {
c++;
}
public void decrement() {
c--;
}
public int value() {
return c;
}
}
public static void main(String[] args) {
Counter counter = new Counter();
Thread t1 = new Thread(new Runnable() {
public void run() {
counter.increment();
System.out.println(counter.value());
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
counter.decrement();
System.out.println(counter.value());
}
});
t1.start();
t2.start();
}
}

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()) {}
}
}
}

Please help me to resolve illegalmonitorstate exception in the code

//The below code is throwing illegalmonitorstate exception.
public class Multithreading implements Runnable {
static int i=0;
public boolean ist1=true;
public boolean ist2=false;
public static void main (String args[]){
Multithreading ins= new Multithreading();
Thread t1 =new Thread(ins);
Thread t2 =new Thread(ins);
t1.setName("Even");
t2.setName("ODD");
t1.start();
t2.start();
}
#Override
// Wanted to right run method used by two threads to print
// even and odd number in sequence
public void run() {
while(i<=9){
try{
if(Thread.currentThread().getName().contains("Even")&& i%2==0){
System.out.println(Thread.currentThread().getName()+"________"+i);
i=i+1;
Thread.currentThread().wait(100);
}
// due to wait is not used with synchronized but
// i am not able to correct it
if(Thread.currentThread().getName().contains("ODD") && i%2>=1){
System.out.println(Thread.currentThread().getName()+"________"+i);
i=i+1;
Thread.currentThread().wait(100);
//System.out.println(e);
}
}catch(Exception e){
System.out.println(e);
}
}
}
}
To pause a thread, you need to use Thread.sleep() in your case instead of wait().

Categories