diff --git a/app/src/main/java/edu/sharif/prj01/BusyWaitSignal.java b/app/src/main/java/edu/sharif/prj01/BusyWaitSignal.java new file mode 100644 index 0000000..230aa48 --- /dev/null +++ b/app/src/main/java/edu/sharif/prj01/BusyWaitSignal.java @@ -0,0 +1,15 @@ +package edu.sharif.prj01; + +public class BusyWaitSignal { + protected boolean hasDataToProcess = true; + + + public synchronized boolean hasDataToProcess(){ + return this.hasDataToProcess; + } + + public synchronized void setHasDataToProcess(boolean hasData){ + this.hasDataToProcess = hasData; + } + +} diff --git a/app/src/main/java/edu/sharif/prj01/EvenOddPrinter.java b/app/src/main/java/edu/sharif/prj01/EvenOddPrinter.java new file mode 100644 index 0000000..c439301 --- /dev/null +++ b/app/src/main/java/edu/sharif/prj01/EvenOddPrinter.java @@ -0,0 +1,40 @@ +package edu.sharif.prj01; + +import android.util.Log; +import static edu.sharif.prj01.MainActivity.TAG; + +public class EvenOddPrinter { + private volatile boolean isOdd; +// use volatile to have last version from main memory + + synchronized void printEven(int number) { + while (!isOdd) { + try { + wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + System.out.println(Thread.currentThread().getName() + ":" + number); + Log.i(TAG, "OddEven, print even ]]>>" + + Thread.currentThread().getId() + ":" + number + ); + isOdd = false; + notify(); + } + synchronized void printOdd(int number) { + while (isOdd) { + try { + wait(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + System.out.println(Thread.currentThread().getName() + ":" + number); + Log.i(TAG, "OddEven, print odd ]]>>" + + Thread.currentThread().getId() + ":" + number + ); + isOdd = true; + notify(); + } +} diff --git a/app/src/main/java/edu/sharif/prj01/MainActivity.java b/app/src/main/java/edu/sharif/prj01/MainActivity.java index 3c52728..e592c47 100644 --- a/app/src/main/java/edu/sharif/prj01/MainActivity.java +++ b/app/src/main/java/edu/sharif/prj01/MainActivity.java @@ -2,7 +2,9 @@ import android.os.Handler; import android.os.HandlerThread; + import androidx.appcompat.app.AppCompatActivity; + import android.os.Bundle; import android.util.Log; @@ -31,9 +33,9 @@ protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - ThreadSubclass(); +// ThreadSubclass(); // ThreadRunnable(); -// AnonymousRunnable(); + AnonymousRunnable(); // LambdaRunnable(); // RaceCondition(); // SynchronizedThread(); @@ -43,10 +45,104 @@ protected void onCreate(Bundle savedInstanceState) { // ReentrantExampleMethod(); // WaitNotifyTest(); // ScheduledExecutorServiceMethod(); - ProducerConsumerExample(); +// ProducerConsumerExample(); // RockPaperScissor(); // javaThreadHandler(); // androidThreadHandler(); +// busyWaiting(); + evenOdd(); + + } + + private void evenOdd() { + EvenOddPrinter evenOddPrinter = new EvenOddPrinter(); + Thread threadOdd = new Thread(new Runnable() { + public void run() { + int number = 1; + while (number <= 10) { + evenOddPrinter.printOdd(number); + + number += 2; + } + + } + }); + threadOdd.start(); + + Thread threadEven = new Thread(new Runnable() { + public void run() { + int number = 2; + while (number <= 10) { + evenOddPrinter.printEven(number); + + number += 2; + } + + } + }); + threadEven.start(); + + try { + threadOdd.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + try { + threadEven.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + } + + private void busyWaiting() { + BusyWaitSignal sharedSignal = new BusyWaitSignal(); + Thread readerThread = new Thread(new Runnable() { + public void run() { + while (sharedSignal.hasDataToProcess()) { + Log.i(MainActivity.TAG, "Busy Waiting ]]>> " + + + " id: " + Thread.currentThread().getId() + + " is waiting" + ); + } +// doing its job + + } + }); + readerThread.start(); + + Thread writerThread = new Thread(new Runnable() { + public void run() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + sharedSignal.setHasDataToProcess(false); + Log.i(MainActivity.TAG, "Busy Waiting ]]>> " + + + " id: " + Thread.currentThread().getId() + + " finished the job" + ); + } + + } + }); + writerThread.start(); + + try { + readerThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + try { + writerThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } } private void androidThreadHandler() { @@ -64,7 +160,7 @@ public void run() { public void javaThreadHandler() { T t = new T(); t.start(); - while(t.handler == null) { + while (t.handler == null) { synchronized (t) { try { t.wait(); @@ -264,6 +360,34 @@ void ObjectMemberVariablesNotThreadSafe() { } Log.i(MainActivity.TAG, "ObjectMemberVariablesNotThreadSafe]]>>" + sharedInstance.builder.toString()); + +// check for static members + NotThreadSafe instance1 = new NotThreadSafe(); + NotThreadSafe instance2 = new NotThreadSafe(); + + Thread t3 = new Thread(new NotThreadSafe.MyRunnablePrime(instance1)); + Thread t4 = new Thread(new NotThreadSafe.MyRunnablePrime(instance2)); + t3.start(); + t4.start(); + try { + t3.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + try { + t4.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + Log.i(MainActivity.TAG, "ObjectMemberVariablesNotThreadSafeToCheckStaticMembers]]>>" + + " first instance static builder: " + + instance1.staticBuilder.toString() + + " second instance static builder: " + + instance2.staticBuilder.toString() + + ); + + } void ThreadLocalExampleMethod() { diff --git a/app/src/main/java/edu/sharif/prj01/NotThreadSafe.java b/app/src/main/java/edu/sharif/prj01/NotThreadSafe.java index 19056ae..0440aac 100644 --- a/app/src/main/java/edu/sharif/prj01/NotThreadSafe.java +++ b/app/src/main/java/edu/sharif/prj01/NotThreadSafe.java @@ -1,12 +1,18 @@ package edu.sharif.prj01; public class NotThreadSafe{ + static StringBuilder staticBuilder = new StringBuilder(); StringBuilder builder = new StringBuilder(); + public void add(String text){ this.builder.append(text); } + public void addToStaticBuilder(String text){ + staticBuilder.append(text); + } + public static class MyRunnable implements Runnable{ NotThreadSafe instance = null; @@ -18,4 +24,16 @@ public void run(){ this.instance.add("some text"); } } + + public static class MyRunnablePrime implements Runnable{ + NotThreadSafe instance = null; + + public MyRunnablePrime(NotThreadSafe instance){ + this.instance = instance; + } + + public void run(){ + this.instance.addToStaticBuilder("some text"); + } + } } \ No newline at end of file