I have two methods in two different classes, like this
public class ClassX implements Runnable {
public void methodAandB() {
for(int i=0;i<10;i++) {
System.out.println("This is A and B ");
}
}
#Override
public void run() {
methodAandB();
}
}
public class ClassY implements Runnable {
public void methodAorB() {
for(int i=0;i<10;i++) {
System.out.println("This is A or B");
}
}
#Override
public void run() {
methodAorB(a);
}
}
Thread t1 is calling methodAandB().
Thread t2 is calling methodAorB().
Can I switch between these two threads after each iteration of loop in methods?
I want to get output like this:
This is A and B
This is A or B
This is A and B
This is A or B
This is A and B
This is A or B
This is A and B
This is A or B
Best example of flip-flop between threads:
Given two int array (even and odd), 2 threads printing their numbers in natural order.
package com.rough;
public class ThreadsBehaviour {
static Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
int a[] = {1,3,5,7,9};
int b[] = {2,4,6,8,10};
Thread odd = new Thread(new Looper(a, lock));
Thread even = new Thread(new Looper(b, lock));
odd.start();
even.start();
}
}
class Looper implements Runnable
{
int a[];
Object lock;
public Looper(int a[], Object lock)
{
this.a = a;
this.lock = lock;
}
#Override
public void run() {
for(int i = 0; i < a.length; i++)
{
synchronized(lock)
{
System.out.print(a[i]);
try
{
lock.notify();
if(i == (a.length - 1))
{
break;
}
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
You can achieve this simply by using the shared variables. I have implemented and verified the problem. code is below
class X
public class ClassX implements Runnable {
public void methodAandB() {
for(int i=0;i<10;i++) {
while(GlobalClass.isClassXdone)
{}
System.out.println("This is A and B ");
GlobalClass.isClassXdone = true;
GlobalClass.isClassYdone = false;
}}
#Override
public void run() {
methodAandB(); } }
ClassY
public class ClassY implements Runnable {
public void methodAorB() {
for(int i=0;i<10;i++) {
while(GlobalClass.isClassYdone)
{}
System.out.println("This is A or B ");
GlobalClass.isClassYdone = true;
GlobalClass.isClassXdone = false;}}
#Override
public void run() {
methodAorB();}}
Definition of the shared variable
public class GlobalClass {
public static boolean isClassXdone = false ;
public static boolean isClassYdone = false ;
}
You can just start your thread using t1.start and t2.start to get the desired output
Thread t1 = new Thread(new ClassX());
Thread t2 = new Thread(new ClassY());
t1.start();
t2.start();
This is probably more than needed to solve the problem, but, as it seems to be an introduction to concurrent programming exercise, it should be along the lines of what you'll encounter.
You should probably have a shared object that both your threads know, so that they may synchronize through it. Like so:
public class MyMutex {
private int whoGoes;
private int howMany;
public MyMutex(int first, int max) {
whoGoes = first;
howMany = max;
}
public synchronized int getWhoGoes() { return whoGoes; }
public synchronized void switchTurns() {
whoGoes = (whoGoes + 1) % howMany;
notifyAll();
}
public synchronized void waitForMyTurn(int id) throws
InterruptedException {
while (whoGoes != id) { wait(); }
}
}
Now, your classes should receive their respective identifier, and this shared object.
public class ClassX implements Runnable {
private final int MY_ID;
private final MyMutex MUTEX;
public ClassX(int id, MyMutex mutex) {
MY_ID = id;
MUTEX = mutex;
}
public void methodAandB() {
for(int i = 0; i < 10; i++) {
try {
MUTEX.waitForMyTurn(MY_ID);
System.out.println("This is A and B ");
MUTEX.switchTurns();
} catch (InterruptedException ex) {
// Handle it...
}
}
}
#Override
public void run() { methodAandB(); }
}
ClassY should do the same. Wait for its turn, do its action, and then yield the turn to the other.
I know it's a little late to answer this. But it's yesterday only I have come across this question. So I guess it's never too late.. ;)
Solution, as #afsantos mentioned is having a shared object between the two threads and implementing mutual exclusion on the shared object. The shared object could be alternatively locked by the two threads. Two possible implementations are as follows. This is actually more like an extension of #afsantos solution. His work is hereby acknowledged.
Solution 1:
Blueprint of the object that will be shared is as follows.
public class MutEx {
public int whoGoes, howMany;
public MutEx(int whoGoes, int howMany) {
this.whoGoes = whoGoes;
this.howMany = howMany;
}
public synchronized void switchTurns(){
this.whoGoes = (this.whoGoes + 1) % 2;
notifyAll();
}
public synchronized void waitForTurn(int id) throws InterruptedException{
while(this.whoGoes != id)
wait();
}
}
Then, you could implement the ClassX as follows.
public class ClassX implements Runnable {
private final int MY_ID;
private final MutEx MUT_EX;
public ThreadOne(int MY_ID, MutEx MUT_EX) {
this.MY_ID = MY_ID;
this.MUT_EX = MUT_EX;
}
#Override
public void run(){
this.doTheWork();
}
public void doTheWork(){
for(int i = 0; i < 10; i++){
try {
MUT_EX.waitForMyTurn(MY_ID);
System.out.println("This is A and B");
MUT_EX.switchTurns();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
ClassY also will be the same, with whatever the differences you need to be there. Then, in the invocation (i.e. in the main method),
public static void main(String[] args) {
MutEx mutEx = new MutEx(0, 2);
Thread t1 = new Thread(new ClassX(0, mutEx);
Thread t2 = new Thread(new ClassY(1, mutEx));
t1.start();
t2.start();
}
Voila! You have two threads, alternating between each as you need.
Solution 2: Alternatively, you could implement the ClassX & ClassY as follows.
public class ClassX extends Thread{
Here, you are subclassing the java.lang.Thread to implement your requirement. For this to be invoked, change the main method as follows.
public static void main(String[] args) {
MutEx mutEx = new MutEx(0, 2);
ClassX t1 = new ClassX(0, mutEx);
ClassY t2 = new ClassY(1, mutEx);
t1.start();
t2.start();
}
Run this, and you have the same result.
If you don't need to use Thread try this code:
for (int i = 0; i < 20; i++) {
if (i % 2 == 0) {
methodAandB();
} else {
methodAorB();
}
}
Related
```
package programs;
public class TestThreads {
public static void main(String[] args) {
ThreadOne t1 = new ThreadOne();
ThreadTwo t2 = new ThreadTwo();
Thread one = new Thread(t1);
Thread two = new Thread(t2);
one.start();
two.start();
}
}
class Accum{
private static Accum a = new Accum();
private int counter = 0;
private Accum() {
}
public static Accum getAccum() {
return a;
}
public void updateCounter(int add) {
counter +=add;
}
public int getCount() {
return counter;
}
}
class ThreadOne implements Runnable{
Accum a = Accum.getAccum();
#Override
public void run() {
for(int x=0;x<98;x++) {
a.updateCounter(1000);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("one "+ a.getCount());
}
}
class ThreadTwo implements Runnable{
Accum a = Accum.getAccum();
#Override
public void run() {
for(int x=0;x<99;x++) {
a.updateCounter(1);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("two "+ a.getCount());
}
}
```
The expected output should be as below
One 98098
Two 98099
But I am getting values same for both One and Two.
Is this expected or both should result in different values?
When it comes to thread priorities eventhough the jvm scheduler takes the role to choose the turn of which thread should execute first, what about the results of this program where two void run programs of for loop with 98 and 99 which should result in two different values else the same
This is because shared data is NOT synchronized.
To resolve this problem, use synchronized on methods those touch the shared data, to make Accum class Thread-Safe.
example:
class Accum{
private static Accum a = new Accum();
private int counter = 0;
private Accum() {
}
public static Accum getAccum() {
return a;
}
public synchronized void updateCounter(int add) {
counter +=add;
}
public synchronized int getCount() {
return counter;
}
}
Maybe make the methods and fields in the Accum class static, because then it is saved in a general place and not an instance...
Code:
class Accum{
private static Accum a = new Accum();
private static int counter = 0;
private Accum() {
}
public static Accum getAccum() {
return a;
}
public static void updateCounter(int add) {
counter +=add;
}
public static int getCount() {
return counter;
}
}
class ThreadTwo implements Runnable{
#Override
public void run() {
for(int x=0;x<99;x++) {
Accum.updateCounter(1);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("two "+ Accum.getCount());
}
}
class ThreadOne implements Runnable{
#Override
public void run() {
for(int x=0;x<98;x++) {
Accum.updateCounter(1000);
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("one "+ Accum.getCount());
}
}
I am not very experienced in Java yet, so this might not work...
[EDIT] I tested it and I believe it works
Hi I have implemented my code like below two snippets but still I am not able to achieve synchronization in threads, as my methods are synchronized still no thread is waiting for other till complete. can you please let me know what mistake did I make in below snippet?
but when I put sleep on Thread in between then it works fine but that is not better way to implement by putting sleep on Thread
Option 1:
public class A{
public static void main(String args[]){
C c = new C();
ExecutorService executorService = Executors.newFixedThreadPool(10);
B t1 = new B(c);
for(int i = 1; i <=10; i++) {
executorService.submit(/*new B(c)*/t1);
}
executorService.shutdown();
try{
executorService.awaitTermination(Long.MAX_VALUE,TimeUnit.NANOSECONDS);
}catch(InterruptedException e){
System.out.println("Error while checking tread life: "+e);
}
}
}
public class B extends Thread{
C c;
static final Object lockObject = new Object();
public B(C c) {
this.c = c;
}
public void run(){
someProcess();
}
synchronized public void someProcess(){
String something = c.C();
if(something == null || "".equalsIgnoreCase(something)){
c.A();
}else{
c.B();
}
}
}
public class C {
synchronized public void method A(){
//insert the recods
}
synchronized public void method B(){
//update the records
}
synchronized public String method C(){
// searching a record to get it's id if it exist
return something;
}
}
Option 2:
public class A {
public static void main(String args[]) {
C c = new C();
ExecutorService executorService = Executors.newFixedThreadPool(10);
B t1 = new B(c);
for(int i = 1; i <=10; i++) {
executorService.submit(/*new B(c)*/t1);
}
if(executorService !=null) {
executorService.shutdown();
try {
executorService.awaitTermination (Long.MAX_VALUE,TimeUnit.NANOSECONDS);
}catch(InterruptedException e) {
System.out.println("Error while checking tread life: "+e);
}
}
}
}
public class B extends Thread {
C c;
static final Object lockObject = new Object();
public B(C c) {
this.c = c;
}
public void run() {
someProcess();
}
public void someProcess() {
synchronized(this) {
String something = c.C();
if(something == null || "".equalsIgnoreCase(something)) {
c.A();
}else{
c.B();
}
}
}
}
public class C {
synchronized public void method A() {
//insert the recods
}
synchronized public void method B() {
//update the records
}
synchronized public String method C() {
// searching a record to get it's id if it exist
return something;
}
}
Option 3:
public class A {
public static void main(String args[]) {
C c = new C();
ExecutorService executorService = Executors.newFixedThreadPool(10);
B t1 = new B(c);
for(int i = 1; i <=10; i++) {
executorService.submit(/*new B(c)*/t1);
}
if(executorService !=null) {
executorService.shutdown();
try {
executorService.awaitTermination (Long.MAX_VALUE,TimeUnit.NANOSECONDS);
}catch(InterruptedException e) {
System.out.println("Error while checking tread life: "+e);
}
}
}
}
public class B extends Thread {
C c;
static final Object lockObject = new Object();
public B(C c) {
this.c = c;
}
public void run() {
someProcess();
}
public void someProcess() {
synchronized(this) {
String something = c.C();
if(something == null || "".equalsIgnoreCase(something)) {
c.A();
}else{
c.B();
}
}
}
}
public class C {
public void method A() {
synchronized(this) {
//insert the recods
}
}
public void method B() {
synchronized(this) {
//update the records
}
}
public String method C() {
synchronized(this) {
// searching a record to get it's id if it exist
return something;
}
}
}
Option 4:
public class A {
public static void main(String args[]) {
C c = new C();
ExecutorService executorService = Executors.newFixedThreadPool(10);
B t1 = new B(c);
for(int i = 1; i <=10; i++) {
executorService.submit(/*new B(c)*/t1);
}
if(executorService !=null) {
executorService.shutdown();
try {
executorService.awaitTermination (Long.MAX_VALUE,TimeUnit.NANOSECONDS);
}catch(InterruptedException e) {
System.out.println("Error while checking tread life: "+e);
}
}
}
}
public class B extends Thread {
C c;
static final Object lockObject = new Object();
public B(C c) {
this.c = c;
}
public void run() {
someProcess();
}
public void someProcess() {
synchronized(lockObject) {
String something = c.C(lockObject);
if(something == null || "".equalsIgnoreCase(something)) {
c.A(lockObject);
}else{
c.B(lockObject);
}
}
}
}
public class C {
public void method A(Object lockObject) {
synchronized(lockObject) {
//insert the recods
}
}
public void method B(Object lockObject) {
synchronized(lockObject) {
//update the records
}
}
public String method C(Object lockObject) {
synchronized(lockObject) {
// searching a record to get it's id if it exist
return something;
}
}
}
class hehe implements Runnable {
static int count = 0;
public synchronized void count() {
count++;
}
public void run() {
for (int i = 0; i < 10000; i++) {
count();
}
}
}
public class Sychronise {
public static void main(String[] args) {
Thread a1 = new Thread(new hehe());
Thread a2 = new Thread(new hehe());
a1.start();
a2.start();
try {
a1.join();
a2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(hehe.count);
}
}
The count should be 20000, but my output is still unstable.
Currently, your synchronized does nothing as it's synchronizing on each individual 'hehe' instance. To make it synchronize on the Class object (which owns the 'count' variable) make your count method static too:
public static synchronized void count(){
count++;
}
Or synchronize on an object:
public class hehe implements Runnable {
static int count= 0;
static Object lock = new Object();
public void count(){
synchronized(lock) {
count++;
}
}
public void run(){
for (int i=0;i<10000;i++){
count();
}
}
}
The issue here is that your count method is synchronized but there are 2 instances of the object Hehe, so each synchronization would be scoped to each instance, in this case I would suggest to use an AtomicInteger
First try with a static count method.
public static synchronized void count(){
count++;
}
public void run(){
for (int i=0;i<10000;i++){
Hehe.count();
}
}
I try to write some code about Lock and synchronized and to compare their performance difference.
Code:
public abstract class Task {
public abstract int getTotal();
}
// Lock test class
public class TaskWithLock extends Task implements Runnable {
private static int total = 0;
private final Lock lock = new ReentrantLock();
public void run() {
try {
lock.lock();
doSomething();
} finally {
lock.unlock();
}
}
private void doSomething() {
total++;
}
public int getTotal() {
return total;
}
}
// Synchronized test class
public class TaskWithSync extends Task implements Runnable {
private static int total = 0;
public void run() {
synchronized ("") {
doSomething();
}
}
private void doSomething() {
total++;
}
public int getTotal() {
return total;
}
}
// Test class
public class Test {
public static void main(String[] args) throws Exception {
int count = 100000;
runTasks(TaskWithLock.class, count);
runTasks(TaskWithSync.class, count);
}
public static void runTasks(Class<? extends Runnable> clazz, int count)
throws Exception {
List<Thread> list = new ArrayList<Thread>(count);
for (int i = 0; i < count; i++) {
list.add(new Thread(clazz.newInstance()));
}
for (int i = 0; i < count; i++) {
list.get(i).start();
}
for (int i = 0; i < count; i++) {
list.get(i).join();
}
System.out.println(clazz.getSimpleName() + "Total Result: "
+ ((Task) clazz.newInstance()).getTotal());
}
}
My understand is the above Lock and synchronized code block should be the same effect, but the result I run them are not same, synchronized code is right, it is always 100000, but lock code is always incorrect, sometimes 99995,or 99997, or other result, but it is not 100000.
Console:
TaskWithLock Result: 99991
TaskWithSync Result: 100000
I think my code should have some error, or my understand about Lock is wrong, or Lock can not be used like this.
Please point out what could be wrong.
In the lock-version, you are using one lock per instance. That means that every thread has its own lock, which ultimately renders the locks useless because no two threads use the same lock.
You need to change this to one central lock for all threads. Add static to this line:
private final Lock lock = new ReentrantLock();
so it becomes
private static final Lock lock = new ReentrantLock();
Because your lock object is per instance and you are updating a static variable. So each Thread has it's own lock which is quite pointless to use it to protect a static variable.
I am having a trouble to share a resource with three threads...
public class Subject{
int i;
boolean valueSet1 = false;
boolean valueSet2 = true;
boolean valueSet3 = true;
void put(int i){
while(valueSet1){
try{
wait();
}catch(InterruptedException e){
System.out.println("Producer thread interrupted");
}
}
System.out.println("Producer thread wakesup");
valueSet1=true;
valueSet2=false;
this.i=i;
System.out.println("Put: "+i);
notify();
}
void makesquare(){
int a;
while(valueSet2){
try{
System.out.println("Convertor thread goin to sleep");
wait();
}catch(InterruptedException e){
System.out.println("Convertor thread interrupted");
}
}
System.out.println("Convertor thread wakesup");
valueSet2 = true;
valueSet3=false;
a = this.i;
this.i = a*a;
System.out.println("Made: "+i);
notify();
}
void get(){
while(valueSet3){
try{
System.out.println("Consumer thread goin to sleep");
wait();
}catch(InterruptedException e){
System.out.println("Consumer thread interrupted");
}
}
System.out.println("Consumer thread wakesup");
valueSet3 = true;
valueSet1 = false;
System.out.println("Got: "+i);
notify();
}
}
class Producer implements Runnable{
Subject q;
Thread t;
String msg;
Producer(Subject q, String msg){
this.q=q;
this.msg = msg;
t = new Thread(this, this.msg);
}
#Override
public void run(){
int i=2;
while(true){
synchronized(q){
q.put(i++);
}
}
}
}
class Consumer implements Runnable{
Subject q;
Thread t;
String msg;
Consumer(Subject q,String msg){
this.q = q;
this.msg = msg;
t = new Thread(this, this.msg);
}
#Override
public void run(){
while(true){
synchronized(q){
q.get();
}
}
}
}
class Convertor implements Runnable{
Subject q;
Thread t;
String msg;
Convertor(Subject q, String msg){
this.q=q;
this.msg = msg;
t = new Thread(this, this.msg);
}
#Override
public void run(){
while(true){
synchronized(q){
q.makesquare();
}
}
}
}
There are three threads in the program. One thread produces while another makes square of the produced quantity. While the last thread consumes the squared product.They all share the same object.
public class Thread3way {
public static void main(String[] args) {
Subject q = new Subject();
Producer P = new Producer(q, "producer");
Convertor Cv = new Convertor(q, "convertor");
Consumer Cs = new Consumer(q, "consumer");
P.t.start();
Cv.t.start();
Cs.t.start();
}
}
Your wait loop is not quite correct, you need to keep looping until your condition is true before you do any modifications. I'd do it like this (using a State enum to make things clearer):
public class Subject {
static enum State { EMPTY, WAITING_TO_SQUARE, WAITING_TO_GET };
State state;
int value;
public synchronized void put(int i) {
while (state != State.EMPTY) {
try {
wait();
}catch(InterruptedException e) {
System.out.println("Put interrupted");
}
}
value = i;
state = State.WAITING_TO_SQUARE;
}
}
As a commenter pointed out, you don't need to synchronize twice, either synchronized(q) around the Subject calls, or declare your methods synchronized. You don't need both.
No need to use Runnables explicitly, just make Producer, Convertor, and Consumer Threads directly. Then you don't need the t fields, and you can start the threads like P.start().
Sounds to me like you're doing some kind of pipeline with 3 stages. Why not enjoy the benefits of ExecutorService:
class ConvertorTask implements Runnable {
private int number;
private static ExecutorService consumer = Executors.newSingleThreadExecutor();
public ConvertorTask(int number) {
this.number = number;
}
public void run() {
consumer.submit(new ConsumerTask(number * number));
}
}
class ConsumerTask implements Runnable {
private int number;
public ConsumerTask(int number) {
this.number = number;
}
public void run() {
System.out.println(number);
}
}
class Producer implements Runnable {
private ExecutorService convertor = Executors.newSingleThreadExecutor();
public void run() {
int i = 0;
while(true) {
convertor.submit(new ConvertorTask(i++));
}
}
}
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Producer());
t.start();
}
}