using threads unable to get the output as expected - java

I am writing a code in java to print the output as follows
[spirit]
[of]
[wipro]
but i am facing a problem in setting the priorities of the threads and seeing each threads priorty and not getting output as expected.
class shobj
{
public synchronized void sharedMethod(String arg)
{
System.out.print("[");
System.out.print(arg);
try
{
Thread.sleep(1000);
}
catch(Exception e)
{
System.out.println("INTERRUPTED");
}
System.out.println("]");
}
}
class thread1 implements Runnable
{
String arg;
shobj obj1;
Thread t;
public thread1(shobj obj1,String arg)
{
this.obj1=obj1;
this.arg=arg;
t=new Thread(this);
t.start();
// System.out.println(t.currentThread());
}
public void run()
{
obj1.sharedMethod(arg);
}
}
class synchro
{
public static void main(String args[])
{
shobj ob = new shobj();
thread1 x1 = new thread1(ob,"spirit");
thread1 x2 = new thread1(ob,"of");
thread1 x3 = new thread1(ob,"wipro");
x3.t.setPriority(Thread.NORM_PRIORITY+3);
x2.t.setPriority(Thread.NORM_PRIORITY+2);
x1.t.setPriority(Thread.NORM_PRIORITY+1);
try
{
x1.t.join(); //System.out.println(x1.t.currentThread());
x2.t.join();//System.out.println(x2.t.currentThread());
x3.t.join();//System.out.println(x3.t.currentThread());
}
catch(Exception e)
{
System.out.println("Interruted Exception");
}
}
}
I am getting output as follows:
[spirit]
[wipro]
[of]

See How are Java Thread priorities translated to an OS thread priority? how the thread priority is mapped to the native OS. There is no guarantee that different thread priorities in java lead to different priority on OS level.

Priority is just a hint to the OS. If you have plenty of free CPU, all thread which want to run, can run.
This means all the threads in your case could run in any order which is what having multiple threads is designed to.

Related

Thread and concurrency hickup

i'm wondering what the code would look like in order to have a program which creates a loop on start. This loop then creates several, thread objects all on their own threads so their all running at the same time, and they all run the same code. Is there a way to do this? as in for example we make 2 threads, they never stop looping and one is always prinintg "thread 1" and 1 is always printing "thread 2" at the same time. This is what i'm wondering. Thanks in advance!
class MyTask implements Runnable {
public static id = 0;
public MyTask(){
id++;
}
public void run(){
while(true){
System.out.print("Thread " + id);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Generator{
Public static void main(String[] args){
Runnable[] myTasks = new Runnable[2];
myTasks[0] = new MyTask();
myTasks[1] = new MyTask();
for(Runnable r: myTasks){
Thread t = new Thread(r);
t.start();
}
}
}
I didn't compile it. but this is how you are going to do.
When you run class Generator, two Threads will start, and they will print Thread 1. and thread 2 once every one second forever.

Notifying two threads at the same time

How can I notify Thread t1 and Thread t2 at the same time (so it is the same probability to get hey 1 as hey2 first)? I've tried notifyAll, but couldn't make it work.
class Thr extends Thread
{
Thr () throws InterruptedException
{
Thread t1 = new Thread() {
public synchronized void run()
{
while (true)
{
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try
{
Thread.sleep(1500);
} catch (Exception e) { }
System.out.println("hey 1");
}
}
};
Thread t2 = new Thread() {
public synchronized void run()
{
while (true)
{
try {
wait();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
try
{
Thread.sleep(1500);
} catch (Exception e) { }
System.out.println("hey 2");
}
}
};
t1.start();
t2.start();
}
public static void main(String args[]) throws InterruptedException
{
new Thr();
}
}
You should wait on a shared object and use notifyAll as in:
class Thr extends Thread
{
Thr () throws InterruptedException
{
final Object lock = new Object ();
Thread t1 = new Thread() {
public void run()
{
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("hey 1");
}
};
Thread t2 = new Thread() {
public synchronized void run()
{
try {
synchronized (lock) {
lock.wait();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println("hey 2");
}
};
t1.start();
t2.start();
synchronized (lock) {
lock.notifyAll ();
}
}
public static void main(String args[]) throws InterruptedException
{
new Thr();
}
}
The right way to do this is to use notifyAll. The real problem with your code seems to be that you have two threads waiting for notifications on different mutexes. You need them to wait on a single object ... as described in #ShyJ's answer.
Note that there is NO WAY that you can code this so that the notification is guaranteed to be delivered first to either thread with equal probability:
The Java threading specs make no guarantees of fairness in wait / notify.
The thread scheduler implemented (typically) at the OS-level (typically) makes no such guarantees either.
The point is that the application has no control over this. The best approach is to just let wait/notifyAll do what they normally do, and design your application so that any bias in the thread scheduling does not affect the application's behaviour in an important way.
(FWIW, the usual problem is that people explicitly or implicitly assume non-randomness ... and get burned when threads get scheduled in an unexpectedly random order.)
I highly recommend avoiding the use of wait/notify and use something more robust. The problem is that using wait/notify in any combination will likely result in a race condition.
The only way to give equal probability to them academically is to create two Semaphore objects, have the threads try to acquire them, and use Random to choose which one to release first. Even then, if the scheduler decides to run the first one that tried to obtain the lock, then you get bias there anyway, regardless of whether or not the Sempahore is fair. This forces you to wait until the first thread is done before running the second, such as via Thread.join.
Bottom line, the only way to guarantee order in a concurrent system is to force them into a single-threaded format, which throws out the whole point of having them concurrent in the first place.
If you are using Java versions greater than 1.4, then it would greatly simplyfy your task by using any of the concurrent locks:
java.util.concurrent.locks specially the ReadWrite type.
For now for message passing to all the threads at the same type - implement Observer Pattern

IllgalThreadStateException

I am writing a multithreaded program in which i am getting exception java.lang.IllegalThreadStateException.
Any help would be welcomed
here is my stack trace
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
at GeoMain.main(GeoMain.java:18)
here is my code for main class
public class TMain {
public static void main(String[] args) {
String Batchid="1,2,3";
String batch[]=StringUtils.split(Batchid,",");
MultiThread gt=new MultiThread();
for(int i=0;i<batch.length;i++){
gt.setBatch(batch[i]);
gt.start();
System.out.println("Thread started for "+batch[i]);
}
System.out.println("mainfinish");
}
}
and hereis my multi thread class
public class MultiThread extends Thread {
private static Queue<String> queue = new LinkedList<String>();
private static Boolean isInUse = false;
private void runcoder()
{
String batchid=null;
BatchIdCreator bid=null;
while(isInUse)
{
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
System.out.println("exception");
e.printStackTrace();
}
}
isInUse=true;
synchronized(isInUse)
{
isInUse=true;
batchid=queue.poll();
System.out.println(batchid);
System.out.println(batchid);
bid=new BatchIdCreator(batchid);
// get a list from database
bid.getList();
// print on console
bid.printList();
isInUse=false;
}
}
#Override
public void run() {
runcoder();
}
public void setBatch(String batchid)
{
queue.add(batchid);
}
public static Boolean getIsInUse() {
return isInUse;
}
}
In this snippet:
MultiThread gt=new MultiThread();
for(int i=0;i<batch.length;i++){
gt.setBatch(batch[i]);
gt.start(); <--- Same thread object as in previous iteration
System.out.println("Thread started for "+batch[i]);
}
you're calling start() over and over again on the same thread. As described in the documentation, this is illegal:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
You may want to move the new MultiThread() into the loop to avoid this:
----------.
for(int i=0;i<batch.length;i++){ |
|
MultiThread gt=new MultiThread(); <--'
gt.setBatch(batch[i]);
gt.start();
System.out.println("Thread started for "+batch[i]);
}
You cannot start the same thread twice. You you want to create several threads move the creation of thread instance into the loop:
for(int i=0;i<batch.length;i++){
MultiThread gt=new MultiThread();
gt.setBatch(batch[i]);
gt.start();
System.out.println("Thread started for "+batch[i]);
}
You are attempting to start the same (Multi)Thread instance multiple times. Create a new instance of Multithread inside the loop, so each thread gets its own instance.

getting inconsistent/wrong output in the program Multi -Threading java

/*
This should always produce 0 as output since all three methods increment(), decrement(), value() are thread safe(synchronized). but it is returning 1
*/
class Counter implements Runnable {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
public void run() {
try {
this.increment();
Thread.sleep(1000);
this.decrement();
Thread.sleep(1000);
this.increment();
Thread.sleep(1000);
this.decrement();
Thread.sleep(1000);
}
catch (InterruptedException e){
return;
}
}
public static void main(String args[]) throws InterruptedException {
Counter c = new Counter();
new Thread(c).start();
new Thread(c).start();
System.out.println(c.value());
}
}
like everyone else said you need to make sure that the treads have finished executing, to do that you need to call join. for example
public static void main(String args[]) throws InterruptedException {
Counter c = new Counter();
Thread t1 = new Thread(c).start();
Thread t2 = new Thread(c).start();
t1.join();
t2.join();
System.out.println(c.value());
}
that should run correctly
There's nothing to control when the main thread is calling value(). It will run as soon as it can acquire a lock on c, even though the other threads are still running.
If you want to wait until the threads are done, call join() on them.
You are reading the value before the threads have finished execution, so it may be well different from zero.
You're not waiting for the threads to complete running, so the result is that the value of c is printed at whatever it is at that second. I bet if you tried it 1000 times, there would be times when it wasn't 1.
IBM has a fair tutorial on the situation you're encountering:
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzahw/rzahwex3rx.htm

concurrency in java - how to test it?

I'm on Java concurrency at the moment.
I don't know how to write negative scenario test.
I need a way to make deadlocks and I need a way to see that without using synchronization
I could end up with problems like inconsistency.
What is generally best way to write some stress test code
that could show me bad results if synch is omitted?
Any code example would be really appriciated.
Thank you all in advance!
The following code will almost certainly create a deadlock and demonstrates the classic deadlock scenario whereby two different threads acquire locks in an inconsistent order.
public class Main {
private final Object lockA = new Object();
private final Object lockB = new Object();
public static void main(String[] args) {
new Main();
}
public Main() {
new Thread(new Runnable() {
public void run() {
a();
sleep(3000L); // Add a delay here to increase chance of deadlock.
b();
}
}, "Thread-A").start();
new Thread(new Runnable() {
public void run() {
// Note: Second thread acquires locks in the reverse order of the first!
b();
sleep(3000L); // Add a delay here to increase chance of deadlock.
a();
}
}, "Thread-A").start();
}
private void a() {
log("Trying to acquire lock A.");
synchronized(lockA) {
log("Acquired lock A.");
}
}
private void b() {
log("Trying to acquire lock B.");
synchronized(lockB) {
log("Acquired lock B.");
}
}
private void sleep(long millis) {
try {
Thread.sleep(millis);
} catch(InterruptedException ex) {
}
}
private void log(String msg) {
System.err.println(String.format("Thread: %s, Message: %s",
Thread.currentThread().getName(), msg));
}
}
The following code demonstrates a situation likely to create inconsistent results due to lack of concurrency control between two threads.
public class Main {
// Non-volatile integer "result".
private int i;
public static void main(String[] args) {
new Main();
}
public Main() {
Thread t1 = new Thread(new Runnable() {
public void run() {
countUp();
}
}, "Thread-1");
Thread t2 = new Thread(new Runnable() {
public void run() {
countDown();
}
}, "Thread-2");
t1.start();
t2.start();
// Wait for two threads to complete.
t1.join();
t2.join();
// Print out result. With correct concurrency control we expect the result to
// be 0. A non-zero result indicates incorrect use of concurrency. Also note
// that the result may vary between runs because of this.
System.err.println("i: " + i);
}
private void countUp() {
// Increment instance variable i 1000,000 times. The variable is not marked
// as volatile, nor is it accessed within a synchronized block and hence
// there is no guarantee that the value of i will be reconciled back to main
// memory following the increment.
for (int j=0; j<1000000; ++j) {
++i;
}
}
private void countDown() {
// Decrement instance variable i 1000,000 times. Same consistency problems
// as mentioned above.
for (int j=0; j<1000000; ++j) {
--i;
}
}
}
In above deadlock example. Period for deadlock is 3 second. After which lockA and lockB are released and occupied by Thread 2 and Thread 1

Categories

Resources