Signaling with shared objects - java

I am not able to understand, where to place methods
hasDataToProcess() & setHasDataToProcess() of MySignal class,
in App9 class to maintain synchronization on object of type NotThreadSafe.
Please help me the know the place !!!
//Signalling via shared objects
Code:
class MySignal{
protected boolean hasDataToProcess = false;
public synchronized boolean hasDataToProcess(){
return this.hasDataToProcess;
}
public synchronized void setHasDataToProcess(boolean hasData){
this.hasDataToProcess = true;
}
}
class NotThreadSafe{
StringBuilder builder = new StringBuilder();
public void add(String text){
this.builder.append(text);
}
public void display(){
System.out.println(builder);
}
}
public class App9 extends Thread {
NotThreadSafe instance;
protected MySignal sharedSignal = new MySignal();
public App9(NotThreadSafe sharedInstance){
this.instance = sharedInstance;
}
#Override
public void run(){
this.instance.add("sham");
this.instance.display();
}
public static void main(String[] args) {
NotThreadSafe sharedInstance = new NotThreadSafe();
for(int i=0; i<10 ; i++){
Thread t = new App9(sharedInstance);
t.start();
}
}
}

Related

I expect infinite loop,but not,why?

code like this
for test two case
one is have volatile keywords ,can stop
other is without volatile,the thread infinite loop
public class VolatileTest extends Thread {
public boolean flag = false;
public static void main(String[] args) throws InterruptedException {
VolatileTest volatileTest = new VolatileTest();
volatileTest.start();
Thread.sleep(1000);
volatileTest.flag = true;
}
#Override
public void run() {
while (!flag) {
System.out.println("=====>");
}
}
}
My mistake. The problem is that you are calling a synchronized method inside your while loop. Try it like this. Stopped will never print unless you redeclare flag as volatile.
public class VolatileTest extends Thread {
public boolean flag = false;
public static void main(String[] args) throws InterruptedException {
VolatileTest volatileTest = new VolatileTest();
volatileTest.start();
Thread.sleep(1000);
volatileTest.flag = true;
System.out.println("flag is now " + flag);
}
#Override
public void run() {
int i = 0;
while (!flag) {
i++;
}
System.out.println("stopped");
}
}

I have a 100 threads but only 60 instances

I have a singleton class and a method with an endless loop. I would like to call that a hundred times with 100 threads inside getInstance. The threads are created, but I only have 60-70 object which are created by the infinite loop.
I'm open to any idea.
I've already tried with newCachedThreadPool and newFixedThreadPool.
public final class MyClass {
private static MyClass instance = null;
public static boolean stop;
private static Map<Integer, CustomBean> pieces = new HashMap<>();
public static MyClass getInstance() {
if (instance == null) {
instance = new MyClass();
for (int i = 0; i < 100; i++) {
Executors.newSingleThreadExecutor().execute(() -> {
try {
endlessMagic();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
return instance;
}
public static void endlessMagic() throws InterruptedException {
while (!stop) {
// where magic happens
pieces.put(something);
Thread.sleep(20);
}
}
}
public class MyClassServletContextListener implements ServletContextListener {
#Override public void contextInitialized(ServletContextEvent servletContextEvent) {
MyClass.getInstance();
}
#Override public void contextDestroyed(ServletContextEvent servletContextEvent) {
MyClass.stop = true;
}
}

synchronized before field outside of new Thread()

I want to make a part of asynchronous. I added a new Thread() and put to it code. What have to be done with fields and methods outside?
public class Record {
private String actionDetails;
public void setActionDetails(String actionDetails) {
this.actionDetails = actionDetails;
}
}
public class Recorder {
private Record record;
public void record(Record record){
this.record = record;
}
}
public class Test {
private static Recorder recorder = new Recorder();
private static StringBuilder builder;
public static void main(String[] args) {
builder.append("Test");
new Thread(() -> {
final Record record = new Record();
record.setActionDetails(builder.toString());
recorder.record(record);
}).start();
}
}
I think that for recorder, record(), setActionDetails() should use synchronized modificator and use StringBuffer instead StringBuilder.

How to switch between two thread back and forth

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

How to use non static method (observer method) in static main

want to use non static method in static main, but i cant. I know this problem but, because i use INotificationObserver, i cant make registerObserver as static. So i could solve my problem.
How can i solve this problem ?? Thanks .
non-static variable this cannot be referenced from a static context
Test
public class PushTest implements INotificationObserver{
NotificationService ns = NotificationService.getInstance();
public static void main(String[] args) {
try {
ns.registerObserver(this); // How can i register ???
Interface
public interface INotificationSubject {
public void registerObserver(INotificationObserver o);
public void removeObserver(INotificationObserver o);
public void notifyObserver(PushedNotification notification);
}
*NotificationService *
public class NotificationService implements INotificationSubject{
protected static final Logger logger = Logger.getLogger(NotificationService.class);
private volatile static NotificationService uniqueFactory;
private ArrayList observers;
private NotificationService() {
observers = new ArrayList();
}
public static NotificationService getInstance() {
if (uniqueFactory == null) {
synchronized (NotificationService.class) {
if (uniqueFactory == null) {
uniqueFactory = new NotificationService();
}
}
}
return uniqueFactory;
}
public static INotification GetNotificationObject(DeviceTypes Types) {
INotification messageSender = null;
if (Types == Types.IOS) {
messageSender = new IosNotification();
}
return messageSender;
}
public void registerObserver(INotificationObserver o) {
observers.add(o);
}
public void removeObserver(INotificationObserver o) {
int i =
observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
public void notifyObserver(PushedNotification notification) {
for (int i = 0; i < observers.size(); i++) {
INotificationObserver observer = (INotificationObserver) observers.get(i);
observer.update(notification);
}
}
public void messageSendInfo(PushedNotification notification) {
notifyObserver(notification);
}
public void showSentInfo(PushedNotification notification) {
messageSendInfo(notification);
}
}
You need an instance:
INotificationObserver ino = new PushTest();
ns.registerObserver(ino);
Therefor, you don't need the ns attribute.
typical solution for this is initialize your class in the main method:
public class PushTest implements INotificationObserver{
NotificationService ns = NotificationService.getInstance();
public static void main(String[] args) {
PushTest pushTest = new Pushtest();
...
etc etc

Categories

Resources