Second thread is not reached - java

I am trying to start 2 threads, one for tcp and one for udp
package com.main;
import com.utility.HibernateUtil;
public class ServerStarter {
public static void main(String[] args) {
System.out.print("Reach 1");
Thread tcp = new Thread(new TcpServerStarter());
tcp.start();
System.out.print("Reach 2");
Thread udp = new Thread(new UdpServerStarter());
System.out.print("Reach 3");
HibernateUtil.buildSessionFactory();
System.out.print("Reach 4");
}
public static class TcpServerStarter extends Thread{
public TcpServerStarter(){
new TcpServer(8500).run();
}
}
public static class UdpServerStarter extends Thread{
public UdpServerStarter(){
new UdpServer(1000).run();
}
}
}
Only "reach 1" is printed. I read that this may occur if i have single core, however i have 2 cores.

When you call new TcpServer(8500).run(); in TcpServerStarter's constructor
It starts running the tcpServer in the MAIN thread.
I'm guessing that it just serves forever and this is why it doesn't reach any of the following code.
Also what Zbynek said : you didn't start the udp thread.

You only create udp thread but not really start it. Add this:
udp.start();
Secondly you start the loop directly from the constructor instead of run method. Change to:
public static class TcpServerStarter implements Runnable {
public void run(){
new TcpServer(8500).run();
}
}
And similarly for the UdpServerStarter.

Put the code into method called run() instead of calling it from the constructor (calling the run() will block the execution)
public static class TcpServerStarter extends Thread {
#Override
public void run() {
new TcpServer(8500).run();
}
}
public static class UdpServerStarter extends Thread {
#Override
public void run() {
new UdpServer(1000).run();
}
}
}
If the UdpServer and TcpServer already extends Thread or implements Runnable, you can start them directly by the start() method w/o creating the wrapper classes.

Without changing too much your code, this one works. I am not sure what is your specific implementation fo TcpServer or UdpServer looks like. So implemented some dummy ones for now. I see that all the print outs print as expected.
package network;
class TcpServer implements Runnable{
TcpServer(int port){
}
#Override
public void run() {
for (int i=0; i < 10; i++){
System.out.println("Thread printing:" + i + "tid:" + Thread.currentThread().getId());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class UdpServer implements Runnable{
UdpServer(int port){
}
#Override
public void run() {
for (int i=0; i < 10; i++){
System.out.println("Thread printing:" + i + "tid:" + Thread.currentThread().getId());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ServerStarter {
public static void main(String[] args) {
System.out.print("Reach 1");
Thread tcp = new Thread(new TcpServerStarter());
tcp.start();
System.out.print("Reach 2");
Thread udp = new Thread(new UdpServerStarter());
System.out.print("Reach 3");
//HibernateUtil.buildSessionFactory();
System.out.print("Reach 4");
}
public static class TcpServerStarter extends Thread{
public TcpServerStarter(){
new TcpServer(8500).run();
}
}
public static class UdpServerStarter extends Thread{
public UdpServerStarter(){
new UdpServer(1000).run();
}
}
}

A thread object must be started so that the execution of the corresponding Thread can be initiated.
I see in your code below code
System.out.print("Reach 1");
Thread tcp = new Thread(new `TcpServerStarter`());
Till now you have not yet called the tcp.start(). Till now you have created a new object of Thread.java which is OK but the main problem I feel is with the constructor of TcpServerStarter.java the code written it it prevents the flow of execution of your main method ahead.
See TcpServerStarter.java class is a Thread itself as it extends Thread.java. should override run method in your TcpServerStarter.java You Should move the code from the constructor to the run() method. Instead of creating the objects of `Thread.java modify the code as below.
Thread tcp = new `TcpServerStarter`();
Then you need to call start on the Thread object you have created.
tcp.start()
Similarly you need to modify the code including the usage of UdpServerStarter.

Related

Threads and SynchronousQueue

I've got problem with my code.
My task is wrtie program, which will resemble some factory producing pancake and I have to use a synchronous queue.
There is three steps:
1. Frying.
After that in another thread:
2. Greasing.
And the last one is:
3. Rolling up this pancake:)
In my program I start frying and I create "put", which means I'm waiting for call "take" in another method. But it doesn't work. It stops when the program wants to call "greasing" method in Greasing class.
main:
public static void main(String[] args) {
Factory f1 = new Factory();
f1.start();
Greasing g1 = new Greasing(f1);
g1.start();
RollingUp r1 = new RollingUp(f1);
r1.start();
}
Factory Class:
public class Factory extends Thread{
// 0 - frying
// 1 - greasing
// 2 - rolling up
SynchronousQueue<String> list = new SynchronousQueue<>();
#Override
public void run() {
try{
while(true) frying();
}catch(InterruptedException e){
e.printStackTrace();
}
}
private synchronized void frying()throws InterruptedException{
System.out.println("I'm frying now");
list.put("Frying");
notify();
}
public synchronized void greasing() throws InterruptedException{
notify();
list.take();
System.out.println("I'm greasing now");
list.put("Greasing");
}
public synchronized void rollingup()throws InterruptedException{
notify();
list.take();
System.out.println("I'm rolling up now");
list.put("Rolling up");
}
}
Greasing class:
public class Greasing extends Thread{
Factory f1;
public Greasing(Factory f1) {
this.f1 = f1;
}
#Override
public void run() {
try{
while(true){
f1.greasing();
sleep(1000);
}
}catch(Exception e){
e.getMessage();
}
}
}
RollingUp class:
public class RollingUp extends Thread{
Factory f1;
RollingUp(Factory f1){
this.f1 = f1;
}
#Override
public void run() {
try{
while(true){
f1.rollingup();
sleep(1000);
}
}catch(Exception e){
e.getMessage();
}
}
}
You have two kind of problems:
Remove notify() an sychronized from your code, this is blocking you because the synchronized puts a lock on the Factory class, so 2 threads cannot enter the Factory sync methods in the same moment. Better to move the code in the right class, the Greasing must occur in the Greasing class. This will help you to make order and to think as objects.
Fixed the 1. you will see that every operation now take place until when you have all the threads waiting on the put.
This is because you need to have a different queue for every "consumer". In your code you can have a Rollingup triggered from the frying because there is no distinction between the objects in the list.
The Frying operation must put the object in the greasing queue, the Greasing operation must consume from his queue and then put an object in the Rollingup queue

Why run() method defined is not called on call of start by Thread?

I was just experimenting some code around Thread class and I get stuck at something, Well firstly have a look at my code
class ThreadExample implements Runnable
{
String threadName;
Thread thread;
public ThreadExample()
{
thread=new Thread();
thread.start();
}
public void run()
{
System.out.println("Thread "+getThreadName()+" is being executed");
}
void setThreadName(String string)
{
threadName=string;
thread.setName(string);
}
String getThreadName()
{
return thread.getName();
}
public static void main(String string[]) throws InterruptedException
{
ThreadExample threadExample= new ThreadExample();
threadExample.setThreadName("Thread !");
//threadExample=new ThreadExample();
//threadExample.setThreadName("Thread 2");
//threadExample=new ThreadExample();
//threadExample.setThreadName("Thread 3");
Thread.sleep(500);
}
}
Well I think this code is very simple and Everyone should have got my intentions although When I am running this program It just get complete without even calling run() method even I make main Thread to wait for sometime until the child Thread which is ThreadExample completes. I am new to this so sorry if I have forgotten some thing. Thanks in advance.
You created a Runnable type and never passed it into a thread context. You'll want to add it to the Thread. I would do something like:
String threadName;
Thread thread;
public ThreadExample() {
thread=new Thread(this);
}
public void startThread() {
thread.start();
}
The Thread class accepts a Runnable as an argument.
You never call run() method. You rather call start, which you are already doing in ThreadExample() constructor, but it has some mistakes I will explain:
In java you have 2 options to deal with Threads. First is to inherit from Thread class, so you can call start() method from it and the code inside run() will be executed. The second option is to create a Runnable, which seems the option you are choosing, but to run this you have to create a Thread like this:
ThreadExample runnable = new ThreadExample();
Thread myThread = new Thread(threadExample);
And then you can call myThread.start(); when you are ready to start your thread.
As John Vint has pointed out, the Thread class needs a Runnable target. I edited your program a little :
public class NewThreadExample implements Runnable{
String threadName;
public String getThreadName() {
return threadName;
}
public void setThreadName(String threadName) {
this.threadName = threadName;
}
public static void main(String[] args) throws InterruptedException {
NewThreadExample threadTarget = new NewThreadExample();
threadTarget.setThreadName("Dushyant");
Thread thread = new Thread(threadTarget);
System.out.println("Thread created and going to start");
thread.start();
System.out.println("Thread sleeping");
Thread.sleep(2000);
System.out.println("Program done");
}
#Override
public void run() {
System.out.println(this.getThreadName() + " is running...");
}
}
gives
Thread created and going to start
Thread sleeping
Dushyant is running...
Program done
To run this implementation class, create a Thread object, pass Runnable implementation class object to its constructor. Call start() method on thread class to start executing run() method.
You missed following two lines:
Thread thread1 = new Thread(threadExample);
thread1.start();
class ThreadExample implements Runnable
{
String threadName;
Thread thread;
public ThreadExample()
{
}
public void run()
{
System.out.println("Thread "+getThreadName()+" is being executed");
}
void setThreadName(String string)
{
threadName=string;
thread.setName(string);
}
String getThreadName()
{
return thread.getName();
}
public static void main(String string[]) throws InterruptedException
{
ThreadExample threadExample= new ThreadExample();
threadExample.setThreadName("Thread !");
//threadExample=new ThreadExample();
//threadExample.setThreadName("Thread 2");
//threadExample=new ThreadExample();
//threadExample.setThreadName("Thread 3");
Thread.sleep(500);
Thread thread1 = new Thread(threadExample);
thread1.start();
}
}

Calling non thread class from thread

My Problem:
I want to run a method from a Thread, which is no Thread but might take some time to execute (e.g. waiting for server response). It is important that my none thread method is in another class (the classes are Objects which are used in other classes too).
If you do this as in the example code, the whole program will pause for 10 seconds, but I want it to continue with other program code.
Is there a good way of doing this?
My code:
MyThread.java (extends Thread)
public Foo foo;
public void run() {
foo.bar();
}
Foo.java
public void bar() {
try {
Thread.sleep(10000);
// Represents other code that takes some time to execute
// (e.g. waiting for server response)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
And a main method:
public static void main(String[] args) {
MyThread t = new MyThread();
t.foo = new Foo();
System.out.println("Starting!");
t.run();
System.out.println("Done!");
}
You don't want to call run() on the Thread, you want to call start().
Assuming MyThread extends Thread, you need to call start() not run().
Calling run() is just calling a method synchronously.
public static void main(String[] args) {
MyThread t = new MyThread();
t.foo = new Foo();
System.out.println("Starting!");
t.start(); // change here
System.out.println("Done!");
}
start() actually starts an OS thread to run your code on.
Use start() rather than run() on your thread. Or else it will be just like the main thread calling a method of another thread which means you are calling wait() on the main thread itself.
don't call run() method directly.
call start() method instead of run() method.
when call run() method directly
this thread go to main stack, and it run one by one.
class MyThread extends Thread{
public Foo foo;
public void run() {
foo.bar();
}
}
class Foo{
public void bar() {
try {
boolean responseCompleted = false;
boolean oneTimeExcution = false;
while(!responseCompleted){
if(!oneTimeExcution){
// Represents other code that takes some time to execute
oneTimeExcution = true;
}
if( your server response completed){
responseCompleted = true;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
MyThread t = new MyThread();
System.out.println("Starting!");
t.start();
System.out.println("Done!");
}

How to pass information to a thread once it has been created

If you look at the code I have two ArrayLists that are called, pressed and released that are global. What I have to do is update those arrays with the keys that are to be pressed, then pass these updated arrays to my Thread, or update the thread.. this is the part where I'm a little lost on what I have to do.
The currently example(untested if runs), is a basic example of what I had in my actual program. When I ran it it would press the buttons once, then it would throw and error, I can't remember the error as I can't test it right now, but it had to do with the way I was using the thread.
QUESTION
How do I pass the arrays to my Thread, once the thread has been started.
Code Example:
import oscP5.OscEventListener;
import oscP5.OscMessage;
import oscP5.OscP5;
import oscP5.OscStatus;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Main implements OscEventListener {
protected BlockingQueue<Integer> _KeyQue = new ArrayBlockingQueue<>(1024);
Producer producer = new Producer(this._KeyQue);
Consumer consumer = new Consumer(this._KeyQue);
ThreadTest threadTest = new ThreadTest(this._KeyQue);
Thread prod;
Thread con;
Thread threadT;
OscP5 osc = new OscP5(this, 22556);
public static void main(String[] argv) {
Main main = new Main();
main.setup();
}
public void setup() {
prod = new Thread(producer);
con = new Thread(consumer);
threadT = new Thread(threadTest);
prod.start();
con.start();
threadT.start();
}
#Override
public void oscEvent(OscMessage theMessage) {
float val = Float.parseFloat(theMessage.arguments()[0].toString());
if (val == 1.0) {
producer.addKey(KeyEvent.VK_W);
producer.addKey(KeyEvent.VK_S);
} else {
consumer.removeKey(KeyEvent.VK_S);
}
threadTest.run();
}
#Override
public void oscStatus(OscStatus theStatus) {}
public class Producer implements Runnable {
protected BlockingQueue<Integer> _KeyQue = null;
public void addKey(int key) {
try {
this._KeyQue.put(key);
System.out.println("Key " + key +" added to queue");
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
public Producer(BlockingQueue<Integer> _KeyQue) {
this._KeyQue = _KeyQue;
}
public void run() {
}
}
public class Consumer implements Runnable {
protected BlockingQueue<Integer> _KeyQue = null;
public void removeKey(int key) {
try {
this._KeyQue.remove(key);
System.out.println("key " + key + " removed from queue");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public Consumer(BlockingQueue<Integer> _KeyQue) {
this._KeyQue = _KeyQue;
}
public void run() {
}
}
public class ThreadTest implements Runnable {
protected BlockingQueue<Integer> _KeyQue = null;
public ThreadTest(BlockingQueue<Integer> _KeyQue) {
this._KeyQue = _KeyQue;
}
public void run() {
try {
Robot robot = new Robot();
while(!this._KeyQue.isEmpty()) {
for (Integer x : this._KeyQue) {
System.out.println("Keys in que: " + x);
Thread.sleep(500);
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
Edit:
Ok, so I've taken a look at threads and BlockingQueue's, but the thing I still can't figure out is how to continue to run the ThreadTest's run() method without locking the program. In this example it doesn't run at all. When I directly call threadTest.run() it locks the program within it and doesn't allow for adding or removing elements.
So what I need to do is be able to run a thread in the background that is constantly running, looping through *_KeysQueue()* and, in this example, printout the number associated with the keys. This should all happen while allowing me to add and remove keys.
You can have a BlockingQueue and a method to add elements that would be called from every other thread. You can have a static method addKey that could be accessed from every other thread and that would look for adding the new key to the BlockingQueue.
You can use there the producer-consumer pattern and you can see the book Java Concurrency In Practice or the link that led me to the book, in the blog The Java Specialists. The book has examples of all queues, concurrent or synchronized lists, ways to implement code to do several things, and all without having to stop to read 50 pages about something. An example and a few paragraphs of every issue.
Have a setter method in your class
public class ThreadTest implements Runnable {
....
public void setPressedList(ArrayList<Integer> e) {
this.pressed = e;
}
public void setReleasedList(ArrayList<Integer> f)
{
this.released = f
}
}
ArrayList are not thread-safe so you should not used them this way : it could work or it could fail.
Moreover you should use some kind of synchronization mechanism instead of busy-waiting which consume resources for nothing.
So have a look at the BlockingQueue collection which will give you a simple data-passing mechanism between your threads.

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.

Categories

Resources