I am new to java and I am just trying to get feel of this language with the following example.Can anyone tell why the following program only shows:
calling prod
calling cons
import java.util.concurrent.*;
public class Trial5 {
static public void main(String[] arg){
new Prod();
new Cons();
}
}
class Q {
static Semaphore semc = new Semaphore(0);
static Semaphore semp = new Semaphore(1);
static int q[];
}
class Cons implements Runnable{
Thread t;
Cons () {
System.out.println("calling cons");
Thread t = new Thread();
t.start();
}
public void run () {
System.out.println("Running semc");
try {
System.out.println ("Waiting for Data.Acquiring semc");
Q.semc.acquire ();
if(Q.q[0] != 0) {
System.out.println(Q.q[0]);
Q.q[0] = 0;
} else {
wait ();
}
System.out.println ("Releasing semc");
Q.semc.release ();
}
catch (Exception e) {
System.out.println (e.getMessage());
}
}
}
class Prod implements Runnable {
Thread t;
Prod () {
System.out.println ("calling prod");
t = new Thread ();
t.start ();
}
public void run() {
System.out.println ("running semp");
try {
System.out.println ("Waiting for Data.Acquiring semp");
Q.semp.acquire ();
if (Q.q[0] == 0) {
System.out.println ("setting value semp");
Q.q[0] = 10;
} else {
Thread.sleep(100);
}
System.out.println ("Releasing semp");
Q.semp.release ();
}
catch (Exception e) {
System.out.println (e.getMessage());
}
}
}
Your problem isn't with Semaphore, it's with your threads. Your run method is not executing because you're instantiating new instances of Thread which have no idea about the classes you've created and running those rather than doing anything with the classes you've created. So your run methods are never getting called.
Specifically, the lines like this:
Thread t = new Thread();
t.start();
have no reference to the classes they are contained in. They just create a new Thread object which has only the default run method and then start it.
This site has examples of how Threads get run (either through extending Thread or by implementing Runnable). You're going to have to restructure your code some to get it to work, though. Although it might work to simply change the lines to read
Thread t = new Thread(this);
that's a bad idea since you'd be passing the object as a value while its constructor is still running. A better idea would be to have your main method construct each object and then use them to start the threads running.
Furthermore:
Always use semaphores in a
try-finally block. So that whatever
happens you always release the
semaphore, otherwise a deadlock is
bound to happen.
You're calling 'wait()' (which is is a method of the Runnable (inherited from Object) instance) but you can't because you don't own the lock. For more on this see Monitor
Thread.sleep(100) actually throws an InterruptedException: catch it and re-interrupt the thread as the interrupted flag is cleared when InterruptedException is thrown. For more on this topic see for instance Dealing with InterruptedException
You need to do
t = new Prod();
and
t= new Cons();
see here for further reference:
http://www.exampledepot.com/egs/java.lang/BasicThread.html
Related
I am trying to implement Linux pipe operator | using java. The basic idea is assigning connected PipedInputStream and PipeOutputStream to the two commands and they can perform their actions simultaneously.
The implementation is as follows:
PipedOutputStream pOutputStream = new PipedOutputStream();
PipedInputStream pInputStream = new PipedInputStream();
pOutputStream.connect(pInputStream);
Thread thread1, thread2;
thread1 = new Thread(){
public void run() {
try {
new Call(pipe.cmd1).eval(CommandHandler.this, inputStream, pOutputStream);
pOutputStream.close();
} catch (Exception e) {
thread2.interrupt(); // cannot do this as it may not have been initialized
}
}
};
thread2 = new Thread() {
public void run() {
try{
new Pipe(pipe.cmd2).eval(CommandHandler.this, pInputStream, outputStream);
// pInputStream.close();
} catch (Exception e) {
// kill the first thread when the second one raises an exception
thread1.interrupt();
throw e;
}
}
};
thread1.start();
thread2.start();
// waiting for the two threads to die before carry on
thread2.join();
thread1.join();
I would like to interrupt the second thread when the first one raises an exception, just like what I did in thread2 catch. The problem is thread2 is assigned latter so I cannot access it within thread1. I tried to inialize thread1&2 with null values but then they have to be final since they are in an enclosing scope.
Forgive me if it is a stupid question, I just get started to explore multi-threading in java.
** UPDATE **
Thanks to Phil's suggestions. I changed the two anonymous inner classes to two inner classes that extends Thread.
class Thread1 extends Thread{
public Thread counterThread;
public void run() {
try {
new Call(pipe.cmd1).eval(CommandHandler.this, inputStream, pOutputStream);
pOutputStream.close();
} catch (Exception e) {
// kill thread 2
if (counterThread != null) counterThread.interrupt();
}
}
public void setThread(Thread thread) {
counterThread = thread;
}
};
class Thread2 extends Thread {
public Thread counterThread;
public void run() {
try{
new Pipe(pipe.cmd2).eval(CommandHandler.this, pInputStream, outputStream);
// pInputStream.close();
} catch (Exception e) {
// kill the first thread when the second one raises an exception
if (counterThread != null) counterThread.interrupt();
throw e;
}
}
public void setThread(Thread thread) {
counterThread = thread;
}
};
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();
thread1.setThread(thread2);
thread2.setThread(thread1);
Given the code you've started with, two possibilities come to mind. There may be better ideas, but here they are:
(1) Add an additional public method in your anonymous inner class definition that allows you to store a reference to an external thread to be messaged/interrupted. After you create both threads, store a reference of each in the other.
(2) Store a reference to a class (possible the same class that creates and launches the threads) that will hold references to each thread. Have the catch method call a method in that launching class that will message (via loose coupling pattern) or interrupt the counterpart.
I want to run two threads one after the other, without using sleep() or Locks, but a deadlock happens! What's wrong with my code? I used wait() and notifyAll() and an Object object.
public class Test {
public static void main(String[] args) throws InterruptedException {
PrintChar a = new PrintChar('a');
PrintChar b = new PrintChar('b');
Thread ta = new Thread(a);
Thread tb = new Thread(b);
ta.start();
tb.start();
}
}
class PrintChar implements Runnable {
final Object o = new Object();
char ch;
public PrintChar(char a) {
ch = a;
}
#Override
public void run() {
for (int i = 0; i < 100; i++) {
synchronized (o) {
System.out.print(ch);
try {
o.wait();
o.notifyAll();
} catch (InterruptedException ex) {
}
}
}
}
}
Running your code, and looking at it, I've found that each thread you generated was generating and synchronizing to its own object, therefore preventing them from notifying each other. I've also found that you wait before notify, so you do not ever get to invoke o.notifyAll(), as o.wait() stops it first.
Change final Object o = new Object() to static final Object o = new Object(), and switch the places of o.wait() and o.notifyAll()
I think the synchronized block is causing the deadlock. Cos it won't let the other thread start until current one finished. You are using wait() method to make the current thread wait. Ok, it will wait but since it is in synchronized block, it will be in the current thread forever never let any other thread to came into existence because of synchronized.
One thing you can do to make the other thread work is using Thread.stop. Try calling stop method in current thread's reference. But I am not sure whether it will let the current thread to start again.
public class TestSynchronization {
public static void main(String[] args) {
ThreadTest[] threads = new ThreadTest[10];
int i = 0;
for(Thread th : threads) {
th = new Thread(Integer.toString(i++));
th.start();
}
}
class ThreadTest extends Thread {
TestSynchronization ts = new TestSynchronization();
public /*synchronized */void run() {
synchronized(this) {
ts.testingOneThreadEntry(this);
System.out.println(new Date());
System.out.println("Hey! I just came out and it was fun... ");
this.notify();
}
}
}
private synchronized void testingOneThreadEntry(Thread threadInside) {
System.out.println(threadInside.getName() + " is in");
System.out.println("Hey! I am inside and I am enjoying");
try {
threadInside.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I am not able to start the ThreadTest instances.
I expect that ThreadTest's run method be executed as soon as the line th.start(); is executed, the one inside main method.
When I run the program, I see niether my system.out nor any exception.
I debugged also, but could see loop runs 10 times.
You just started a Thread, not a ThreadTest. Thread's run() method does nothing. Instead, create and start() a ThreadTest.
for(ThreadTest th : threads) {
th = new ThreadTest(Integer.toString(i++));
th.start();
}
You'll also need a one-arg constructor in your ThreadTest class that will take the String you're passing to it.
public ThreadTest(String msg){
super(msg);
}
You'll also need to make the ThreadTest class static so you can access that nested class from the static main method.
static class ThreadTest extends Thread {
However, you'll wind up will all Threads waiting. As written, this code will call wait inside every Thread, but it will never get to notify. The notify method must be called on the Thread to be notified, from another Thread. If it's waiting, then it can never notify itself.
You have array of ThreadTest (thread) class which is not used.
I assume you wanted this:
public static void main(String[] args) {
ThreadTest[] threads = new ThreadTest[10];
int i = 0;
for(int i=0;i<threads.length;i++) {
threads[i] = new ThreadTest();
threads[i].start();
}
}
i have a task to make 3 (A,B,C) services depending on each other. When service A starts, service B can start, when service B starts , service C can start and when C stops, B can stop, and when B stops A can stop.
I have manage to start threads and make a switch from one to another with status option. I have to say that i dont know so much things about java but i have just started to learn java so i'm new in this so any help,suggestion and etc would be great.
Also I have 3 almost the same classes so can anyone tell em how can I replace those 3 classes with one? Is there any way?
Here is my code:
public class service_class {
int status=1;
public static void main(String[] args) {
service_class service_class = new service_class();
A1 a=new A1(service_class);
B1 b=new B1(service_class);
C1 c=new C1(service_class);
a.start();
b.start();
c.start();
}
}
class A1 extends Thread{
service_class service_class;
A1(service_class service_class){
this.service_class = service_class;
}
#Override
public void run() {
try{
synchronized (service_class) {
while(service_class.status!=1){
service_class.wait();
}
System.out.print("A started" + "\n");
service_class.status = 2;
service_class.notifyAll();
while(service_class.status!=7){
service_class.wait();
}
System.out.print("A stoped" + "\n");
service_class.status = 1;
service_class.notifyAll();
}
}catch (Exception e) {
System.out.println("Exception 1 :"+e.getMessage());
}
}
}
class B1 extends Thread{
service_class service_class;
B1(service_class service_class){
this.service_class = service_class;
}
#Override
public void run() {
try{
synchronized (service_class) {
while(service_class.status!=2){
service_class.wait();
}
System.out.print("B started " + "\n");
service_class.status = 4;
service_class.notifyAll();
while(service_class.status!=6){
service_class.wait();
}
System.out.print("B stoped" + "\n");
service_class.status = 7;
service_class.notifyAll();
}
}catch (Exception e) {
System.out.println("Exception 2 :"+e.getMessage());
}
}
}
class C1 extends Thread{
service_class service_class;
C1(service_class service_class){
this.service_class = service_class;
}
#Override
public void run() {
try{
synchronized (service_class) {
while(service_class.status!=4){
service_class.wait();
}
System.out.print("C started" + "\n");
service_class.status = 5;
service_class.notifyAll();
while(service_class.status!=5){
service_class.wait();
}
System.out.print("C stoped" + "\n");
service_class.status = 6;
service_class.notifyAll();
}
}catch (Exception e) {
System.out.println("Exception 4 :"+e.getMessage());
};
}
}
I have 3 almost the same classes so can anyone tell em how can I replace those 3 classes with one? Is there any way?
It looks like the differences between the 3 classes A, B and C are:
the name string that gets printed, and
the state values that each one tests and sets.
So just replace these with final instance variables, and initialize them with values passed to the (unified) classes constructor.
However ...
Extending Thread is generally thought to be a bad idea. For a start, it makes it difficult to use thread pooling. A better approach is to use the standard Thread class, and pass it a Runnable instance when you construct it. In fact, if you are using thread pooling or and Executor service or whatever, you won't even need to create and manage the threads yourself.
As for the wait / notify stuff, it is easier to use a higher level synchronization construct (such as CountDownLatch).
Use CountDownLatch
A CountDownLatch is initialized with a given count. The await method block until the count reaches zero due to invocations of the countDown() method (by other threads), after which all waiting threads are released. My suggestion is writing a superclass that:
provides a latch with a initial count of 1
accepts another instance of that class or a CountDownLatch that is to be waited before execution
decrements its latch on start
wraps that logic in run and provides an abstract method innerRun where the actual code will be implemented.
abstract class LatchedRunnable extends Runnable {
private CountDownLatch latch=new CountDownLatch(1);
private CountDownLatch wait;
public Foo(LatchedRunnable waitFor) {
this.wait=waitFor.latch;
}
public Foo(CountDownLatch waitFor) {
this.wait=waitFor;
}
final run () {
//wait for the other thread
if (wait!=null)
try {wait.await();}
catch (InterruptedException e) {return;}
//signal that we have started
latch.countDown();
//actually start
innerRun();
}
protected abstract void innerRun(); //do stuff here
}
class Foo extends LatchedRunnable {
Foo(LatchedRunnable waitFor) {super(waitFor);}
protected void innerRun() {...}
}
class Bar extends LatchedRunnable {
Bar(LatchedRunnable waitFor) {super(waitFor);}
protected void innerRun() {...}
}
Foo foo = new Foo(null);
Bar bar = new Bar(foo);
CountDownLatch, in my understanding, is a mechanism to achieve synchronization without entering a deadlock. So here it goes,
Consider, Thread1 performs a task such a file read. Once complete file has been read, another thread could process the file contents and grab certain information. And now a third thread is responsible to copy the information to a DB.
Assume there are multiple clients using the same steps above and in the same order:
FileRead
FileProcessor
DBUpdate
Instead of handling everything sequentially, we create three thread pools.
ThreadPool<FileReaderThread> poolA;
ThreadPool<FileProcessorThread> poolB;
ThreadPool<DBUpdate> poolC;
As a new request comes in, a countdownlatch will be created with an appropriate count. As a thread from poolA completes its work, the count will be decremented. Once this count reaches 0, thread from poolB will be invoked.Similarly another countdownlatch will used to synchronize thread from poolB and poolC. Ideally, we achieve a sequential process with CountDownLatch.
Please correct if something is incorrect.
I want to restart a thread for some use, for example in the below code.
class Ex13 implements Runnable {
int i = 0;
public void run() {
System.out.println("Running " + ++i);
}
public static void main(String[] args) throws Exception {
Thread th1 = new Thread(new Ex13(), "th1");
th1.start();
//th1.join()
Thread th2 = new Thread(th1);
th2.start();
}
}
When I'm executing the above program , some time i'm getting the output as
Running 1
Running 2
and some time i'm getting only
Running 1
After few run i'm getting only
Running 1 as output.
I'm totally surprise about this behavior. Can any one help me understand this.
if I put the join() then i'm getting only Running 1.
You reuse Thread instance, not Runnable. Thread overwrites its run() method to
public void run() {
if (target != null) {
target.run();
}
}
Where target is the Runnable that you give to the constructor. besides that, Thread has an exit() method that is called by the VM, and this method sets target to null (the reason is this bug). So if your first thread has the chance to finish its execution, its run() method is pretty much empty. Adding th1.join() proves it.
If you want to keep some state, you need to keep reference to your Runnable instance, not the Thread. This way run() method will not be altered.
I don't know why do you need this, but (please note that this code doesn't ensure that th1 is ALWAYS executed before th2, though) :
public static class Ex13 implements Runnable {
AtomicInteger i = new AtomicInteger(0);
CountDownLatch latch;
Ex13(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Running " + i.incrementAndGet());
latch.countDown();
}
}
public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(2);
Ex13 r = new Ex13(latch);
Thread th1 = new Thread(r, "th1");
th1.start();
Thread th2 = new Thread(r);
th2.start();
latch.await(); // wait until both theads are executed
System.out.println("Done");
}
You want the incrementing of i to be synchronized, i.e.
public class Ex13 implements Runnable {
int i=0;
public void run() {
System.out.println("Running "+ increment());
}
private synchronized int increment() {
return ++i;
}
}
The Java Tutorial has a very nice explanation of this given a very similar scenario. The problem is that incrementing a variable is not an atomic operation. Each thread needs to read the current state of i before setting it to the new value. Restricting access to incrementing the variable to one thread at a time assures you will get consistent behavior.
To see whats happening in the System.out.println you can also print the thread name:
Thread t = Thread.currentThread();
String name = t.getName();
System.out.println("name=" + name);
I see you call the two threads with the same runnable object, so they will both use the same "i" variable, in order for you to get Running 1 Running 2 you need to synchronize "i"