The following code is confusing me as synchronized key word is not preventing the two threads accessing SafeThread.value at the same time.
While I was running the code, the result is not 20000 as expected.
I also tried to make increment() non static and have the two threads have the same instance of SafeThread. It did not work either. Did I miss anything?
public class MultithreadTesting extends Thread {
public static void main(String[] args) {
MultithreadTesting thread1 = new MultithreadTesting();
MultithreadTesting thread2 = new MultithreadTesting();
thread1.start();
thread2.start();
System.out.println(SafeThread.value);
}
public void run() {
int i = 10000;
while (i > 0) {
SafeThread.increment();
i--;
}
}
}
public class SafeThread {
public static int value = 0;
public synchronized static void increment() {
value++;
}
}
Related
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);
}
}
I have two files, App.java and Runner.java
App.java -->
public class App {
private static Thread thread1 = new Runner(1);
private static Thread thread2 = new Runner(2);
public static void main(String[] args) throws InterruptedException {
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.printf("Count = %d\n", Runner.getCount());
}
}
Runner.java -->
public class Runner extends Thread {
private volatile static int count = 0;
private int option = 0;
private synchronized void increment() {
count++;
}
private synchronized void decrement() {
count--;
}
public Runner(int option) {
this.option = option;
}
public static int getCount() {
return count;
}
#Override
public void run() {
switch (option) {
case 1:
for (int i = 1; i <= 10000; i++) {
increment();
}
break;
case 2:
for (int i = 1; i <= 10000; i++) {
decrement();
}
break;
}
}
}
Here I am trying to create two threads from main thread and access a common variable from both the threads where both the threads will manipulate this common variable at the same time.
I am trying to create a demo for implementation for the synchronized keyword.
In my example, in Runner.java -
I am making Runner class a child class of Thread using extends keyword and overriding the run() method in body.
Next, I am using a constructor to get an option and running the respective code in run() method in a switch - case block. The common variable is count which is static with initial value 0.
There are two methods, both use the synchronized keyword - increment() and decrement() which increase and decrease the value of count by 1 respectively.
For option 1 run() method uses a for loop to run increment() 10,000 times.
For option 2 run() method uses a for loop to run decrement() 10,000 times.
As such the end value of count should be 0.
In App.java -
I am creating two threads - thread1, thread2 which are instances of Runner class and passing constructor argument 1 and 2 respectively.
I am running the two threads using thread.start() and waiting for completion of the two threads using thread.join()
Now, I am printing the value of count. The value is expected to be 0. But it is not. In each execution it is near to 0 but not 0.
So, where am I going wrong and how to correct my code?
count is static meaning there is only one such variable.
Both increment and decrement are not static which means they are synchronized on this - that is two separate Runner instances.
Make those method static:
private synchronized static void increment() {
count++;
}
private synchronized static void decrement() {
count--;
}
or use explicit mutex object:
private static int count = 0;
private static Object mutex = new Object;
private int option = 0;
private void increment() {
synchronized (mutex) {
count++;
}
}
private void decrement() {
synchronized (mutex) {
count--;
}
}
I am working with the synchronization threads where I have three synchronized method and each method will access by individual thread (Total 3 threads in current program )
In our program we are calling one syn method is calling another sync method, below is sample code which is inspired from real application :
public class ThreadTest {
public static synchronized void suncMessage() {
System.out.print("1");
}
public static synchronized void suncMessage2() {
suncMessage();
System.out.print("2");
}
public static synchronized void suncMessage3(String s) {
System.out.print("3m" + s);
}
public static void main(String... at) throws InterruptedException {
Thread t1 = new Thread() {
public void run() {
for (int i = 0; i <= 2; i++) {
suncMessage();
}
}
};
Thread t2 = new Thread() {
public void run() {
for (int i = 0; i <= 2; i++) {
suncMessage2();
}
}
};
Thread t3 = new Thread() {
public void run() {
for (int i = 0; i <= 2; i++) {
suncMessage3("3");
}
}
};
t1.start();
t2.start();
t3.start();
}
}
So my question is, what is impact of calling one synch. method from another synch.?? Is it good practices and how it will impact the complexity of program?
Nice question, but you have to try hard when you are working on this type of scenarios and the performance may effect. Because synchronization is approx 50 time slower than normal method.
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();
}
}
I am new to threads in Java and hence have this doubt. I read that a 'synchronized non-static method block' allows only one thread to enter the block (for one instance of non-static block, of-course). However it doesn't seem to work. Am I missing something?
Look at the following code.
class A extends Thread
{
public void run()
{
B.b.add();
}
}
class B
{
static B b=new B();
int i;
public synchronized void add()
{
i++;
}
}
public class Sample
{
public static void main(String[] args)
{
for(int i=0;i<10;i++)
{
new A().start();
}
System.out.println(B.b.i);
}
}
One problem here is that your main thread doesn't wait for the other threads to finish before it tries to retrieve the result. Using Thread#join works if you want to wait for a single thread, but here we want to wait for all 10. Modifying the program to use CountDownLatch makes the main thread wait until all the threads it created are finished.
Another problem is that the updated value of i isn't guaranteed to be visible. JVM implementations differ about how aggressively they perform optimizations (like delaying refreshes of cached values, or reordering bytecode) that may make the changes to i not visible to the main thread. Adding a synchronized method on the same lock as the add method to fetch the value of i fixes the visibility issue.
import java.util.concurrent.CountDownLatch;
class A extends Thread {
private CountDownLatch latch;
public A(CountDownLatch latch) {
this.latch = latch;
}
#Override public void run() {
B.b.add();
latch.countDown();
}
}
class B {
static B b=new B();
int i;
public synchronized void add() {
i++;
}
public synchronized int getI() {
return i;
}
}
public class Sample {
public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(10);
for(int i=0;i<10;i++) {
new A(latch).start();
}
latch.await();
System.out.println(B.b.getI());
}
}