This a much simplified version of my multithreading project and its just a way to replicate the issue in a simpler way for easy understanding.
So I have two classes startSession.java and main.java
what I am trying to do is to send a variable from startSession.java to main.java and Im also using multithreading. However, the problem I am facing is that everytime I try to retrieve the variable inside main I get a null value.
Inside startSession theres the run method and Setter(setSessionKey(String sess)) and getter(getSessionKey()) methods. I hardcoded a variable to test.
The get method only works inside the run method but when I call getSessionKey() from inside main I get a null as seen below. However, this is only a problem when I am using multithreading. When I dont use multithreading and instead just call the run method from inside main, the variable Im looking for is no longer null.
My question is there a way to send a variable from startSession to main while using multithreading ?
thank you
startSession.java
public class startSession extends Thread {
static String sessionKey;
public void run() {
String createdSession = "83248329";
setSessionKey(createdSession);
System.out.println("Inside run method: " + getSessionKey());
}
public String getSessionKey() {
return sessionKey;
}
public void setSessionKey(String sess) {
sessionKey = sess;
}
}
main.java
package com.Server;
public class Main {
static String session;
public static void main(String[] args) throws InterruptedException {
startSession startSession = new startSession();
startSession.start();
session = startSession.getSessionKey();
System.out.println("Inside Main: " + session);
}
}
with multithreading
without multithreading
Use a BlockingQueue whereby the Thread (Producer) will add to the shared queue and the Main (Consumer) will block on the take
main
public static void main(String[] args) throws Exception {
// example only uses 1024 - check what is best for you
BlockingQueue queue = new ArrayBlockingQueue(1024);
StartSession producer = new StartSession(queue);
....
System.out.println(queue.take());
startSession
String createdSession= "83248329";
queue.add(createdSession);
see https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/BlockingQueue.html
and
https://jenkov.com/tutorials/java-util-concurrent/blockingqueue.html
Related
class B {
public static void main(String[] args) {
}
}
class A {
public static void main(String[] args) {
B.main(args);
}
}
In the above flow, my init method is A.main which in turn calls B.main.
I know calling A.main will spawn a JVM. Does calling B.main inside A.main spawn another JVM?
OR
B.main is JUST another static method once a JVM is started on A.main as init function.
Option 2. The mains are just static methods of each class, and only one JVM is running when making the call from A to B.main(args).
You can also make use of this in JUNIT tests to help check the command line launch behaves as expected, such as
#Test void coverage() {
A.main(new String[] { "a","b" }); // or B.main
// assertions here if there is some output state you could check
}
I've got 2 classes (1 is a basic class, 2nd one extends Thread class) and I'm trying to access an object (class) that is initialized in my thread class on run() using setText()
public class TThread extends Thread{
Patcher pf;
public TThread(String string) {
setName(string);
start();
}
#Override
public void run() {
pf = new Patcher("Checking Serial key..."); //<=== Class initialized here in a separate thread
}
public void setText(String string) {
pf.setText(string); //<=== Trying to access patcher here, throws NullPointerException
}
}
This is how I call TThread
public void myCall(){
TThread tpf = new TThread("pf thread");
//some code later
try{
tpf.setText("blabla");
}
The pf.setText() throws NullPointerException when I'm trying to access patcher from another thread.
How can I get to that thread and access patcher from another class or this class?
This is classic race condition. Because you have two threads, there is no guarantee what will happen first. pf might be accessed by main thread before it's initialized by a background thread.
Right now, your program is unpredictable. Try adding Thread.sleep(100); at the beginning of setText method. It will appear to work correctly, but it might still fail in some specific circumstances.
One way to fix it is to wait in main thread until pf is initialized:
#Override
public synchronized void run() {
pf = new Patcher("Checking Serial key...");
notifyAll();
}
public synchronized void setText(String string) throws InterruptedException {
while(pf==null) {
wait();
}
pf.setText(string);
}
Be careful. If you have not worked with threads before, it might be tricky to get right.
It is a time consuming process to start a new Thread. With a small delay your code will execute successfully:
TThread thread = new TThread("str");
Thread.sleep(1000);
thread.setText("str2");
So the problem is that your thread had no time to execute the run method (and create the instance). You should check the existance of the instance, and wait for it's creation in the setText method - or instantiate it in the TThread's constructor.
In my program I am calling the thread to do some job but the other method of thread class executes before the run method.
public class Verify extends JFrame implements Runnable
{
long Local_cid;
String local_path;
static boolean isIntialised=false;
JProgressBar bar;
final static ArrayList<Long> ContactList=new ArrayList<>();
final static ArrayList<Long> Scanned=new ArrayList<>();
static boolean flag=true;
static boolean Duplicate_flag=true;
boolean[] flags=new boolean[6];
public Verify(long ID,String path)
{
Local_cid=ID;
local_path=path;
}
public boolean[] Return_Flag()
{
System.err.println("Verify Id");
return flags;
}
public void dispose_Frame()
{
System.err.println("Executing First");
dispose();
}
#Override
public void run()
{
System.err.println("This should Executed First");
}
}
When I call this thread via start call the output is as follows:
Verify Id
Executing First
This should Executed First
You should follow the Java coding standard style guides, it will make it much easier for people to read.
There is nothing in the code you have posted that calls Return_Flag() so you must be calling it somewhere else - probably from the code that creates the thread in the first place.
Run is only called once the thread is started, and other threads are still running at the same time and can call whatever methods they like in whatever order they like...
I'm 100% sure that you are calling those methods somewhere in your code before actually starting the thread. Just look more careful and you will find it.
I am beginner in java. I have been studying multithreading. I want to create two threads and these two threads must run separate methods concurrently. Here these threads should call sum and diff method and run simultaneously. But I am getting an error, that method should be of thread type. How to achieve it.
class Demo implements Runnable
{
void sum()
{
//Some lines of code
}
void diff()
{
//Some lines of code
}
public void run ()
{
System.out.println("Inside run");
}
}
class Test
{
public static void main (String []args){
Demo o = new Demo ();
Demo o1 = new Demo ();
Thread th = new Thread (o);
Thread th1= new Thread(o1);
th.start();
th1.start();
o.th.sum(); // getting error here
o1.th1.diff(); // getting error here
}
}
First of all you have a compilation error because you're trying to reference the variable th as a field on an object of type Demo. th is not a field, but rather a local variable and can be referenced directly (i.e. without the o. prefix). Second, sum() and diff() cannot be called against an instance of Thread as those methods are not defined by thread, but rather by your own Demo class.
All that being said, these compilation problems aren't even the root issue for this code. Based on your code it seems you have some fundamental misunderstandings about the syntax and structure of Java programs so it might benefit you to go through some entry-level tutorials before trying to tackle concurrent programming. But, for the sake of completeness here is a brief explanation of what you need to do in order to make your program work.
When you call Thread.start() it's going to fork a thread and call the run() method of the Runnable you passed into that thread object's constructor.
In order to call the two different methods you need to create two different classes that implement runnable and put the two method implementations in each of their run methods.
Example:
public class Sum implements Runnable {
public void run() {
//Add up your numbers
}
}
public class Diff implements Runnable {
public void run() {
//Subtract numbers
}
}
public class Test {
public static void main(String[] args) {
Thread sumThread = new Thread(new Sum());
Thread diffThread = new Thread(new Diff());
sumThread.start();
diffThread.start();
}
}
Assuming that you are getting a compilation error, the statement o.th.sum() is incorrect.
The statement o.th will cause the compiler to look for a public static class level field in the Demo class with the name th. Since there is no such field in Demo class, you get an error.
You are getting this error because you are trying to access the Thread's local variable using the object of the Demo class and you can't call the method directly if you want's it to run it in a separate thread. A new thread will spawn only when you call start() method on thread class and then it will execute the code in run() method.
As per your requirement to create two threads and these two threads must run separate methods concurrently, following code should work.
class Demo implements Runnable
{
public void run ()
{
//sum() method code
}
}
class Demo1 implements Runnable
{
public void run ()
{
//diff() method code
}
}
class Test
{
public static void main (String []args){
Demo o = new Demo ();
Demo1 o1 = new Demo1 ();
Thread th = new Thread (o);
Thread th1= new Thread(o1);
th.start();
th1.start();
}
}
If I want to just test a block of Java code, is there a way to run it without putting it in a function?
Public static void main(String[] args){
//block of code
}
Also, how do I execute a static block of code like below?
static {
//block of code
}
You can create static blocks
public class StackOverflowUser {
public static StackOverflowUser god;
static {
god = new StackOverflowUser("Jon Skeet");
}
//Stoof
}
Which will do something (hopefully) at some point during the program's life span. The truth is, there's no telling when it fires, and it's not well documented and may change from JVM to JVM. It will definitely have fired before you make the first call to that class, but it could have been executed any time between right before your call and JVM init.
You can also create just constructor blocks
public class StackOverflowUser {
private static ArrayList<StackOverflowUser> users = new ArrayList<StackOverflowUser>();
{
users.add(this);
}
//Stoof
}
This will activate before the constructor is called, right before. Basically, right after object creation, but before initialization. Don't try messing with too many fields, because they won't have been set.
In terms of order, all blocks work the same way. Once the first block has been called, the second block, third block, etc. will all follow, as Jayan puts it "in textual order".
Static blocks get executed once the class is loaded or initialized. So if you want to test the code inside the static block, the best way is to create an instance of the class.
if you want to test your code the best way is to use some testing framework like JUnit or testng.
static block will be executed when your class is being loaded first. So it can be used for DB instantiation etc. where you are sure that this block will be executed before your other code run.
simple block {...} will run when you try to create an instance.
Here first this block will be called then the code written below your line containing new keyword will be called.
public class Test3 {
public static void main(String[] args) {
Test3 obj = new Test3();
}
{
System.out.println("hussain akhtar wahid");
}
}
public class StaticBlockTest {
/*
* Some Code Goes Here
*
* */
static {
System.out.println(" Static Block Executed ");
System.exit(0);
}
}
Static block gets executed without the need for the main method and you need to pass the System.exit(0) to terminate the currently running Java Virtual Machine to exit the program execution.