I have two classes, The first one is in charge of creating threads, then those threads need to be notified from the second class
Problem: I cannot find created threads from the second class, getThreadByName() always return null, Any Idea?.
FirstClass
public class class1{
protected void createThread(String uniqueName) throws Exception {
Thread thread = new Thread(new OrderSessionsManager());
thread.setName(uniqueName);
thread.start();
}
}
OrderSessionManager
public class OrderSessionsManager implements Runnable {
public OrderSessionsManager() {
}
#Override
public void run() {
try {
wait();
}catch(Exception e) {
e.printStackTrace();
}
}
SecondClass
public class class2{
protected void notifyThread(String uniqueName) throws Exception {
Thread thread = Utils.getThreadByName(uniqueName);
thread.notify();
}
}
Utils
public class Utils{
public static Thread getThreadByName(String threadName) {
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount();
Thread[] threads = new Thread[noThreads];
currentGroup.enumerate(threads);
List<String>names = new ArrayList<String>();
for (Thread t : threads) {
String tName = t.getName().toString();
names.add(tName);
if (tName.equals(threadName)) return t;
}
return null;
}
}
There are several issues with your code:
1) It breaks Java Code Conventions: class name must start with a
capital letter
2) wait() method must be called by a thread who owns the object's monitor
so you must use something like:
synchronized (this) {
wait();
}
3) notify() method must be called by a thread who owns the object's monitor and by the same object as wait(), in your case OrderSessionsManager's instance.
4) Since you do not specify a ThreadGroup, the thread gets it's ThreadGroup from it's parent. The following code works as expected:
public class Main {
public static void main(String[] args) {
class1 c1 = new class1();
try {
c1.createThread("t1");
} catch (Exception e) {
e.printStackTrace();
}
Thread thread = Utils.getThreadByName("t1");
System.out.println("Thread name " + thread.getName());
}
}
but this happens only because the t1 thread is in the same group as the main thread.
Related
thread t1 is calling test1() method of Test class object ob.
thread t2 is calling test1() method of Test class object ob in synchronized block.
t1 is able to call test1() method of ob even though test1() method call of ob is in synchronised block of thread t2.
The code is given below:
class Test {
void test1() {
while(1 == 1) {
System.out.println(Thread.currentThread().getName() + " test1!");
}
}
void test2() {
while(1 == 1) {
System.out.println(Thread.currentThread().getName() + " test2!");
}
}
}
class NewThread1 implements Runnable {
Thread t;
String name;
Test target;
NewThread1(Test ob, String threadname) {
target = ob;
name = threadname;
t = new Thread(this, name);
}
public void run() {
target.test1();
}
}
class NewThread2 implements Runnable {
Thread t;
String name;
Test target;
NewThread2(Test ob, String threadname) {
target = ob;
name = threadname;
t = new Thread(this, name);
}
public void run() {
synchronized(target) {
target.test1();
}
}
}
class Test1 {
public static void main(String args[]) {
Test ob = new Test();
NewThread1 t1 = new NewThread1(ob, "t1");
NewThread2 t2 = new NewThread2(ob, "t2");
t2.t.start();
t1.t.start();
try {
t1.t.join();
t2.t.join();
} catch(InterruptedException e) {
System.out.println("Main thread interrupted");
}
System.out.println("Main thread exiting");
}
}
Since NewThread1#run() is not synchronized it will not try to get the monitor on the target and it will therefore not be blocked, it can call the method on the target even if another thread holds the monitor of it.
Synchronized can only exclusively lock out other threads if all threads compete against the same monitor with a synchronized section. (It does not matter of you call test1 or test2 the check happens in the synchronize based on the target). What you could do is to make test1 and test2 synchronized methods, then they will try to reserve the monitor of the instance in all cases). Same is not only true for exclusive execution, but also for any memory access guarantees (happens-after) you might want to get out of a synchronized block.
BTW you don’t need different thread classes, if you only use one (the one with the synchronized) it works like expected.
Thread t1 = new NewThread2(ob, "t1");
Thread t2 = new NewThread2(ob, "t2");
However if your scope of locking is narrow, it is much better to localize the locking inside (all) instance methods of the target Test, because then you can never call them with a missing synchronized (and you can switch to other locking primitives without the caller having to know).
void synchronized test1() {
while(1 == 1) {
System.out.println(Thread.currentThread().getName() + " test1!");
}
}
Or
void test1() {
synchronized(this) {
while(1 == 1) {
System.out.println(Thread.currentThread().getName() + " test1!");
}
}
}
This question already has answers here:
Java Wait and Notify: IllegalMonitorStateException
(2 answers)
Closed 4 years ago.
Was trying to practice producer and consumer using a simple counter in java.
Not sure why I am getting a Illegal Monitor State exception on this piece of code.
I have counter rest and counter consume methods which run in their own thread.
The counter itself is a static int volatile field .
The counter class also gives you a lock to
If I change the wait naotify to the following:
Counter.lock.notify();
Counter.lock.wait();
The code works. Dosen't wait() and notify() automatically takes the reference of the lock synchronize is on?
Producer Class
package multithreading;
public class CounterProducer implements Runnable {
public void run() {
try { incrCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void incrCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter < 1) {
System.out.println("Counter Reset");
Counter.counter = 10;
notify();
wait();
}
}
}
}
}
Consumer Class
package multithreading;
public class CounterConsumer implements Runnable {
public void run() {
try { consumeCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void consumeCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter > 0) {
System.out.println("Consumed");
Counter.counter--;
notify();
wait();
}
}
}
}
}
The Counter
public class Counter {
public static volatile int counter;
public static final Object lock = new Object();
}
The Counter
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
The Runner
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
If I change the wait naotify to the following, the code works:
Counter.lock.notify();
Counter.lock.wait();
Every Java method is either a static method of some class or an instance method of some object. If you see a method call that does not contain an explicit class name or object reference, then it is an implicit call to a method belonging to the this object.
That is to say, notify() means the same thing as this.notify(), and wait() means this.wait().
this, refers to the CounterProducer instance when it appears in your CounterProducer.incrCounter() method, and it refers to the CounterConsumer instance when it appears in your CounterConsumer.consumeCounter() method.
I've a core method in my project which I need it to be synchronized in order not to be accessed twice at the same time, and hence I have a thread which uses an instance from this class to access this method, but inside this thread I need to have a long life loop to be used to access the same method with a fixed value so I have to use another thread in order to allow the first thread to move on and complete it's duties, but for sure the method doesn't run from that second thread using the same instance used in the first thread, and somehow I can't instantiate another instance from the class as I have to use this instance exactly, so how to overcome this problem.
below is the problem translated to java:
public class ClassOne {
synchronized public void my_method(int number) {
// Do some Work
}
}
public class ClassTwo {
private void some_method() {
Thread one = new Thread(new Runnable() {
#Override
public void run() {
ClassOne class_one = new ClassOne();
// DO Work
class_one.my_method(0);
run_loop(class_one);
// Complete Work
}
});
one.start();
}
boolean running = true;
private void run_loop(final ClassOne class_one) {
Thread two = new Thread(new Runnable() {
#Override
public void run() {
while (running) {
class_one.my_method(1); // won't run
Thread.sleep(10000);
}
}
});
two.start();
}
}
Actual problem overview:
my_method --- > is to send UDP packets.
the method has to be synchronized otherwise I'll get the socket is already open exception when trying to use it more than once repeatedly.
at some point, I have to send a KeepAlive message repeatedly each 10 seconds, so, I have to launch a separate thread for that which is thread two in run_loop method.
Putting something that will compile and work. I don't see why you need this function to be synchronized. Check the output for this program...The second thread access this method only when the first thread is done accessing (unless you have missed adding some additional code).
class ClassOne {
int criticalData = 1;
synchronized public void my_method(int number) {
// Do some Work
criticalData *= 31;
System.out.println("Critical data:" + criticalData + "[" + Thread.currentThread().getName() + "]");
}
}
class ClassTwo {
boolean running = true;
public void some_method() {
Thread one = new Thread(new Runnable() {
public void run() {
ClassOne class_one = new ClassOne();
// DO Work
class_one.my_method(0);
run_loop(class_one);
// Complete Work
}
});
one.start();
}
public void run_loop(final ClassOne class_one) {
Thread two = new Thread(new Runnable() {
public void run() {
while (running) {
class_one.my_method(1); // won't run
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
two.start();
}
}
public class StackExchangeProblem {
public static void main(String[] args) {
ClassTwo two = new ClassTwo();
two.some_method();
}
}
I have three threads, each thread have to do some manipulation with the instance(q) of same class (Q), periodically (That's why I use Thread.sleep() in the method somecheck). Main task is to make thread execute not at the same time, so at one time can execute only one thread.
I tried to put content of run method each thread into synchronized (q){}, but I do not understand where to put notify and wait methods.
class Q {
boolean somecheck(int threadSleepTime){
//somecheck__section, if I want to stop thread - return false;
try{
Thread.sleep(threadSleepTime);
} catch (InterruptedException e) {
}
return true;
}
}
class threadFirst extends Thread {
private Q q;
threadFirst(Q q){this.q=q;}
public void run(){
do{
//Working with object of class Q
}
while(q.somecheck(10));
}
}
class threadSecond extends Thread {
private Q q;
threadSecond(Q q){this.q=q;}
public void run(){
do{
//Working with object of class Q
}
while(q.somecheck(15));
}
}
class threadThird extends Thread {
private Q q;
threadThird(Q q){this.q=q;}
public void run(){
do{
//Working with object of class Q
}
while(q.somecheck(20));
}
}
class run{
public static void main(String[] args) {
Q q = new Q();
threadFirst t1 = new threadFirst(q);
threadSecond t2 = new threadSecond(q);
threadThird t3 = new threadThird(q);
t1.start();
t2.start();
t3.start();
}
}
You don't need to put any notify() and wait() methods if you use synchronized blocks inside all of the methods, for example:
class threadFirst extends Thread {
...
public void run() {
synchronized (q) {
//your loop here
}
}
...
}
While doing some practices on multi-threading, I found that I can not set the name of the thread in my code. I can use this to refer the current object then why I can not use Thread.currentThread while constructing thread to access current thread. I am bit confusing. please help me.
When actually thread creating? Is it when constructing thread instance or while calling method start() on thread?
what is currentThread means here?
public class RecursiveRunnableTest {
public static void main(String... args){
Thread t = new Thread(new RecursiveRunnable("First thread"));
t.start();
}
}
class RecursiveRunnable implements Runnable {
private String name;
public RecursiveRunnable(String name) {
this.name = name;
Thread.currentThread().setName(this.name); // Expecting to set the name of thread here
}
#Override
public synchronized void run() {
System.out.println(Thread.currentThread().getName()); // displaying Thread-0
System.out.println(this.name); // displaying "First thread"
try{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
}
}
}
Simply because main thread constructs it not the t thread constructs itself. So, you may rewrite to this one (setting thread's name before starting it):
public class RecursiveRunnableTest {
public static void main(String... args){
RecursiveRunnable rr = new RecursiveRunnable("First thread");
Thread t = new Thread(rr);
t.setName(rr.getName());
t.start();
}
}
class RecursiveRunnable implements Runnable{
private String name;
public RecursiveRunnable(String name) {
this.name = name;
}
public String getName(){return this.name;}
#Override
public synchronized void run() {
System.out.println(Thread.currentThread().getName()); // displaying Thread-0
System.out.println(this.name); // displaying "First thread"
try{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
}
}
}
Try doing this instead
Thread t = new Thread(new RecursiveRunnable("First thread"));
t.start();
Thread.sleep(1L);
System.out.println("main thread: " + Thread.currentThread().getName()); // same thread that created the RecrusiveRunnable instance
you will see
main thread: First thread
printed.
This is because the main thread builds the RecursiveRunnable, so
Thread.currentThread().setName(this.name);
is actually changing the name of the main thread, not the thread that the Runnable will eventually run in.
Also
System.out.println(this.name); // displaying "First thread"
is referring to the name field of the RecursiveRunnable object, which you've set to the same value as the main thread.