Java - Thread doesn't want to start - java

I have this console application, but for some reason the thread's run() method doesn't want to start. The code seems long for the first time but I tried to organize it as much as I can.
The result output:
eThread starting!!
So it seems that CarManager.startFunctionalities() gets executed, but the line eThread.start() is not executed at all because the line "started" is not printed out.
Here is the sourcecode.
The main class:
package rpicar.android;
public class AndroidEmulator{
public static void main(String args[]) throws InterruptedException {
CarManager cm = new CarManager ("localhost");
}
}
CarManager:
package rpicar.android;
import rpicar.common.Direction;
import rpicar.common.EnvironmentData;
public class CarManager {
private MotorManager mManager;
private final String RPIADDRESS = "localhost";
private Thread mThread; //motor
private EnvironmentManager eManager;
private Thread eThread;
public CarManager(String rpiAddress) {
//initialize MotorManager
mManager = new MotorManager(RPIADDRESS);
//Make a thread for the Motor commands
mThread = new Thread(mManager);
//Initialize EnvironmentManager
eManager = new EnvironmentManager(RPIADDRESS);
//Makea thread for collecting EnvironmentData
eThread = new Thread (eThread);
startFunctionalities();
}
public void move(Direction d){
this.mManager.setDirection(d);
}
public EnvironmentData getCurrentEnvironmentData(){
return this.eManager.getCurrentEnvironmentData();
}
private void startFunctionalities(){
//Start MotorManager for sending movement commands when needed.
//mThread.start();
//Start EnvironmentManager to collect EnvironmentData
System.out.println("eThread starting!! ");
eThread.start();
}
}
EnvironmentManager:
package rpicar.android;
import rpicar.common.CarComponent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import rpicar.common.EnvironmentData;
public class EnvironmentManager extends CarComponent implements Runnable{
private EnvironmentData currentEnvironmentData;
public EnvironmentManager(String rpiAddress) {
super(rpiAddress, 2176, true);
this.currentEnvironmentData = new EnvironmentData();
}
public synchronized EnvironmentData getCurrentEnvironmentData() {
return currentEnvironmentData;
}
public synchronized void setCurrentEnvironmentData(EnvironmentData currentEnvironmentData) {
this.currentEnvironmentData = currentEnvironmentData;
}
#Override
public void run() {
System.out.println("eThread started!! ");
super.connect();
while(true){
try {
this.setCurrentEnvironmentData((EnvironmentData) super.in.readObject());
} catch (IOException ex) {
super.connect();
} catch (ClassNotFoundException ex) {
Logger.getLogger(EnvironmentManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

When you create your instance of eThread, you accidentally pass the thread itself to the constructor (or according to the order of the operations, you pass null).
You should pass eManager to the constructor instead.
eThread = new Thread (eThread);
Would become
eThread = new Thread (eManager);
You can protect yourself in the future from this mistake by making the eThread a final field, so you cannot use it before you declare it.

Related

Sending data within three threads in java, one after another

I wanted to make an elevator system where you send information from the following:
elevator (data) -> scheduler (buffer) -> floor (receive)
The Floor subsystem and the Elevators are the clients in the system; the Scheduler is the server.
when I pressed run some of the issues were:
class elevator is shown below:
package elevator;
import java.util.HashSet;
import java.util.Set;
public class elevator {
public enum State {
MOVING_UP, MOVING_DOWN, STOPPED
}
private int floor;
private State state;
#SuppressWarnings({ })
private Set<Integer> pressedButtons = (Set<Integer>) new HashSet<Integer>();
public elevator() {
state = State.STOPPED;
}
public int getFloor() {
return floor;
}
public void setFloor(int floor) {
this.floor = floor;
pressedButtons.remove(floor);
}
public State getState() {
return state;
}
public void setState(State s) {
state = s;
}
public boolean isMoving() {
return state == State.MOVING_UP || state == State.MOVING_DOWN;
}
public void buttonPressed(int i) {
pressedButtons.add(i);
}
public Set<Integer> getButtons() {
return pressedButtons;
}
public String toString() {
return "Floor: " + floor + "\n" + "\t State: " + state + "\n";
}
}
Exception in thread "Thread-0" java.lang.ClassCastException: class elevator.HashSet cannot be cast to class java.util.Set (elevator.HashSet is in unnamed module of loader 'app'; java.util.Set is in module java.base of loader 'bootstrap')
at elevator.elevator.(elevator.java:21)
at elevator.elevatorExchange.retrieveData(elevatorExchange.java:30)
at elevator.elevatorExchange.run(elevatorExchange.java:19) at java.base/java.lang.Thread.run(Thread.java:835)
Thread 1: elevator
package elevator;
import java.util.concurrent.BlockingQueue;
public class elevatorExchange implements Runnable{
private BlockingQueue<elevator> messages;
public elevatorExchange(BlockingQueue<elevator> messages) {
this.messages = messages;
}
#Override
public void run() {
try {
elevator elevatorData = retrieveData();
messages.put(elevatorData);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private elevator retrieveData() throws InterruptedException {
Thread.sleep(5000);
elevator elevatorData = new elevator();
return elevatorData;
}
}
Thread 2: Scheduler. Scheduler is only being used as a communication channel from the Floor thread to the Elevator thread
package scheduler;
import java.util.concurrent.BlockingQueue;
import elevator.elevator;
public class Scheduler implements Runnable {
private BlockingQueue<elevator> messages;
public Scheduler(BlockingQueue<elevator> messages) {
this.messages = messages;
}
#Override
public void run() {
elevator elevatorData = messages.take();
}
Thread 3: The floor (this will receive it from the scheduler). This is the part I'm struggling with the most, I am trying to make sure the data passed down to the floor is from the scheduler and not the elevator, but my IDE keeps making changes to the data type that's running a lot of exceptions.
package floor;
import java.util.concurrent.BlockingQueue;
import elevator.elevator;
public class FloorReceiver implements Runnable{
private BlockingQueue<elevator> messages;
public FloorReceiver(BlockingQueue<elevator> messages) {
this.messages = messages;
}
#Override
public void run() {
try {
System.out.println("waiting for data from elevator");
elevator elevatorData = messages.take();
System.out.println("data from elevator" + elevatorData);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Testing:
package floor;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import elevator.elevator;
import elevator.elevatorExchange;
public class elevatorToFloorTest {
public static void main(String[] args) {
BlockingQueue<elevator> messages = new ArrayBlockingQueue<elevator>(1);
elevatorExchange retriever = new elevatorExchange(messages);
FloorReceiver receiver = new FloorReceiver(messages);
new Thread(retriever).start();
new Thread(receiver).start();
}
}
This line is the problem:
private Set<Integer> pressedButtons = (Set<Integer>) new HashSet<Integer>();
The exception message tells us that the HashSet is not a java.util.HashSet but is something you wrote:
class elevator.HashSet cannot be cast to class java.util.Set
i.e., the HashSet is defined in the elevator package.
Your HashSet is not implementing the Set interface. If it were, then you would not need the cast. Since it isn't, the cast cannot magically make it work.
It seems the compiler would have told you, except you used #SuppressWarnings. (I'm not sure what the empty list does).
On the other hand, the code for the elevator class that you have now posted shows an import for java.util.HashSet, not a homebrew implementation. This cannot produce the error shown. Have you failed to rebuild everything?

Why does my singleton class throw a StackOverflowerror?

I have been writing a program. Everything is in program is controlled by the 'Engine' class. I have hence made it a singleton. Here is my current code that runs just fine.
package org.bautista.cybersafe.core;
import javax.swing.SwingUtilities;
import org.bautista.cybersafe.ui.MainUI;
import org.bautista.cybersafe.util.Cache;
import org.bautista.cybersafe.util.Config;
import org.bautista.cybersafe.util.account.Account;
import org.bautista.cybersafe.util.account.AccountManager;
import org.bautista.cybersafe.util.user.User;
import org.bautista.cybersafe.util.user.UserManager;
public class Engine {
private static Engine instance;
private AccountManager accountManager;
private final MainUI ui;
private final UserManager userManager;
private final Config config;
private User currentUser;
private Engine() {
instance = this; //THIS IS LINE 22
if (!Cache.cacheExists()) {
if (!Cache.createCache()) {
System.out.println("Error creating cache.");
}
}
config = new Config();
userManager = new UserManager();
ui = new MainUI();
}
public static Engine getInstance() {
return instance == null ? instance = new Engine() : instance;
}
public void setCurrentUser(User user) {
currentUser = user;
}
public User getCurrentUser() {
return currentUser;
}
public AccountManager getAccountManager() {
return accountManager;
}
public Config getConfig() {
return config;
}
public UserManager getUserManager() {
return userManager;
}
public void logOut() {
currentUser = null;
accountManager = null;
ui.showLogin();
}
public void openAccountViewer(final Account account) {
ui.showAccount(account);
ui.setTitle("Cyber Safe - [" + currentUser.getUsername() + "] -"
+ account.getName());
}
public void openCreateAccountScreen() {
ui.showCreateAccount();
}
public void openCreateUserScreen() {
ui.showCreateUser();
}
public void openLoginScreen() {
ui.showLogin();
ui.setTitle("Cyber Safe");
}
public void openSafeScreen() {
if (accountManager == null) {
accountManager = new AccountManager(currentUser);
}
ui.showSafe();
ui.setTitle("Cyber Safe - [" + currentUser.getUsername() + "]");
}
public void refreshUI() {
ui.refresh();
}
public void updateAccountPreviews() {
ui.updateAccountScroller();
}
public void run() {
try {
SwingUtilities.invokeAndWait(() -> ui.setVisible(true));
} catch (final Exception e) {
e.printStackTrace();
}
}
}
When I comment out line 22
instance = this;
I receive a StackOverflowerror. When I debug the program I find that the Engine constructor is being called repeatedly, as if it were performing recursion, until I final get the error. Why does that happen? Should't my #getInstance() method be initiating instance as a new instance of the 'Engine' class?
Here is the stacktrace:
Exception in thread "main" java.lang.StackOverflowError
at java.io.InputStream.<init>(InputStream.java:45)
at java.io.FileInputStream.<init>(FileInputStream.java:123)
at org.bautista.cybersafe.util.Config.loadProperties(Config.java:67)
at org.bautista.cybersafe.util.Config.<init>(Config.java:29)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:28)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
And here is the full project on Github
Thanks in advance!
The stack trace shows the following loop:
at org.bautista.cybersafe.util.user.UserManager.loadUsers(UserManager.java:73)
at org.bautista.cybersafe.util.user.UserManager.<init>(UserManager.java:20)
at org.bautista.cybersafe.core.Engine.<init>(Engine.java:29)
at org.bautista.cybersafe.core.Engine.getInstance(Engine.java:34)
Engine.getInstance() calls new Engine().
new Engine() calls new UserManager().
new UserManager() calls UserManager.loadUsers().
UserManager.loadUsers() calls Engine.getInstance(), but Engine.instance hasn't been assigned yet, since the previous new Engine() call hasn't returned yet.
This is why assigning Engine.instance in the constructor, before it calls new UserManager(), fixes the problem.
You should reorganize your code to prevent that initialization loop. UserManager and Engine should not be co-dependent during initialization.
Note that doing private static Engine instance = new Engine() as suggested in another answer will not fix your initialization loop.

Getting a result in the future?

I'm looking to get a result from a method which can take a while to complete and doesn't actually return the object, so I'd like to deal with it as effectively as possible. Here's an example of what I'm trying to achieve:
public static void main (String[] args) {
Object obj = someMethod();
System.out.println("The object is" + obj + ", wooh!");
}
public void callObject() {
// Sends request for the object
}
public void receiveObject(Object object) {
// Received the object
}
public Object someMethod() {
callObject();
// delay whilst the object is being received
// return received object once received, but how?
}
The method callObject will call to get the object, however a different method is called with the object in. I want someMethod() to be able to call for the object, and then return what it eventually receives, even though the actual call and receive are separate methods.
I've looked into using FutureTasks and Callables which I think is the way forward, I'm just not too sure how to implement it.
Sorry if I didn't explain myself too well, I'll give more information if necessary.
Thanks!
You could write a method, that kicks of some long running task asynchronously. You would then return a future object, that is empty but gets filled when the long running task is completed. In other programming languages, this is called a promise.
Here is an simple example. I created a method called someLongAsyncOperation which executes something that takes a while. To simulate this, I just sleep for 3 seconds before generating an answer.
import java.util.UUID;
import java.util.concurrent.*;
public class Test {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
public Future<MyAnswer> someLongAsyncOperation(){
Future<MyAnswer> future = executorService.submit(() -> {
Thread.sleep(3000);
return new MyAnswer(UUID.randomUUID().toString());
});
return future;
}
public static void main(String[] args) throws Exception {
System.out.println("calling someLongAsyncOperation ...");
Future<MyAnswer> future = new Test().someLongAsyncOperation();
System.out.println("calling someLongAsyncOperation done.");
// do something else
System.out.println("wait for answer ...");
MyAnswer myAnswer = future.get();
System.out.printf("wait for answer done. Answer is: %s", myAnswer.value);
executorService.shutdown();
}
static class MyAnswer {
final String value;
MyAnswer(String value) {
this.value = value;
}
}
}
If you execute this little test class, you'll see, that someLongAsyncOperation returns fast, but when calling future.get(); we wait for the operation to complete.
You could now do something like starting of more than one longAsyncOperation, so they would run in parallel. And then wait until all of them are done.
Does this work as a starting point for you?
EDIT
You could implement someMethod like this:
public MyAnswer someMethod() throws ExecutionException, InterruptedException {
Future<MyAnswer> future = someLongAsyncOperation(); // kick of async operation
return future.get(); // wait for result
}
Which will make the async operation synchron again, by calling it and waiting for the result.
EDIT2
Here's another example that uses wait/notify:
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test2 {
private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
private Object receivedObject;
private final Object mutex = new Object();
public static void main (String[] args) throws InterruptedException {
Object obj = new Test2().someMethod();
System.out.println("The object is" + obj + ", wooh!");
executorService.shutdown();
}
public void callObject() {
System.out.println("callObject ...");
// Sends request for the object asynchronously!
executorService.submit(() -> {
// some wait time to simulate slow request
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// provide object to callback
receiveObject(UUID.randomUUID().toString());
});
System.out.println("callObject done.");
}
public void receiveObject(Object object) {
System.out.println("receiveObject ...");
synchronized (mutex) {
this.receivedObject = object;
mutex.notify();
}
System.out.println("receiveObject done.");
}
public Object someMethod() throws InterruptedException {
System.out.println("someMethod ...");
synchronized (mutex) {
callObject();
while(this.receivedObject == null){
mutex.wait();
}
}
System.out.println("someMethod done.");
return this.receivedObject;
}
}
someMethod waits until receivedObject exists. receiveObject notifies upon arrival.
You need a callback:
private abstract class Callback<T>{
run(T object);
}
public Object someMethod() {
callObject(new Callback<Object>()
{
#Override
public void run(Object object)
{
System.out.println("The object is" + object + ", wooh!");
}
})
}
public void callObject(Callback<Object> callback) {
// Sends request for the object
callback.run(object);
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class ThreadExample implements Callable<String>{
#Override
public String call() throws Exception {
// TODO Auto-generated method stub
return "Ashish";
}
}
public class FutureThreadExample {
public static void main(String a[]) throws InterruptedException, ExecutionException {
ExecutorService executorService=Executors.newFixedThreadPool(1);
List <Future<String>>objList=new ArrayList<Future<String>>();
for(int i=0;i<10;i++) {
Future<String> obj=executorService.submit(new ThreadExample());
objList.add(obj);
}
for( Future<String> fut:objList) {
System.out.println(fut.get());
}
executorService.shutdown();
}
}

threading using extend Thread

I can get my method threadR to run by a runnable thread, however i cant seem to get threadL to run as a thread and print out to the console
System.out.println("Greetings from Fred! threadL"); from my run thread
What am i doing wrong?
package threads;
import java.util.ArrayList;
import java.util.List;
public class Threads extends Thread implements Runnable {
private final List<Thread> threadList = new ArrayList<>();
private String e,l;
private Thread greetings;
public static void main(String[] args) {
String[] elements = {"Tim","Fred"};
Threads t = new Threads();
for (String e: elements) {
t.threadL(e);
t.threadR(e);
}
for(int index = 0;index<t.threadList.size();index++){
System.out.print(t.threadList.get(index).getName()+ " ID "+ t.threadList.get(index).getId()+"\n");
}
}
public List<Thread> threadL(String l) {
Thread greetings1 = new Thread(l);
greetings1.start();
threadList.add(greetings1);
//System.out.print(greetings.getName()+"\n");
//System.out.print(greetings.getId()+"\n");
return(threadList);
}
public List<Thread> threadR(String f) {
greetings = new Thread(f);
Thread greetingsFromFred = new Thread(greetings) {
#Override
public void run() {
System.out.println("Greetings from Fred! threadR");
}
}; greetingsFromFred.start();
threadList.add(greetings);
//System.out.print(greetings.getName()+"\n");
//System.out.print(greetings.getId()+"\n");
return(threadList);
}
public void run() {
System.out.println("Greetings from Fred! threadL"); //this is what wont run
}
When you pass a String as the only argument to new Thread(String); you are actually setting the Thread name. You probably meant to pass a Runnable to the Thread as such
Thread greetings1 = new Thread(this);
Thread Constructors

Non-static variable this when putting into a static map

I have a static HashMap to which I'm adding a new item like so:
public static void addSession(Session session) {
if(!map.containsKey(session)){
map.put(session, new SessionThread(session));
}
}
SessionThread is declared locally like so:
public class SessionThread implements Runnable {
That map.put line has a compile error of non-static variable this cannot be referenced from a static context. What is causing the error? this is not referenced anywhere in that method, let alone any non-static members. Everything is either static or in the scope of the method.
Entire class...
package me.scratchjava;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
/**
* A class for managing websocket threads.
* #author James Smyth <jimsmyth at datafascia.com>
*/
public class SessionManager {
private static HashMap<Session, SessionThread> map = new HashMap<>();
/**
* Called whenever a new websocket is opened.
* #param session
*/
public static void addSession(Session session) {
if(!map.containsKey(session)){
map.put(session, new SessionThread(session));
}
}
public static void removeSession(Session session){
if(map.containsKey(session)){
map.remove(session);
}
}
public static void sendData(Session session, byte[] bytes){
if(map.containsKey(session)){
map.get(session).send(bytes);
}
}
public class SessionThread implements Runnable {
private Session session;
private boolean alive = true;
private final LinkedList<byte[]> messageQueue = new LinkedList<>();
public SessionThread(Session session){
}
#Override
public void run() {
while (alive) {
if(Thread.interrupted()){
alive = false;
return;
}
synchronized (messageQueue) {
while(!messageQueue.isEmpty()){
byte[] msg = messageQueue.poll();
try {
session.getBasicRemote().sendBinary(ByteBuffer.wrap(msg));
} catch (IOException ex) {
Logger.getLogger(SessionManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
public void send(byte[] bytes) {
synchronized (messageQueue) {
messageQueue.add(bytes);
}
}
public void kill(){
alive = false;
}
}
}
Your SessionThread inner class is not static. That means the compiler generates a constructor to capture the value of this, the enclosing class. Since you're trying to create a new SessionThread in a static method, there is no this to capture. Make the class static.
Edit
#directedition: SessionThread should be a static class. Actually it should be a stand alone interface and class.

Categories

Resources