I am trying to make network calls on a background thread, so I am creating a thread like this:
private val networkThread = Thread("NetworkThread")
init {
networkThread.start()
}
However when I try running something on the thread like this:
networkThread.run {
try {
socket = Socket(ip, port)
} catch (e: java.lang.Exception) {
Log.e(TAG, "Network Error $e")
}
}
I get the following error: Network Error android.os.NetworkOnMainThreadException
Why is this still running on the MainThread? If I create the thread by using a runnable as the param it works, but I am just curious why doing it this way is still counting as the MainThread
private val networkThread = Thread("NetworkThread") creates a thread which does nothing as you haven't override its run method.
networkThread.run {
....
}
run method you are using on networkThread is not the run() method of the Thread class but is the scope function of Kotlin which gives the context object as the receiver and returns the lambda result, that is why you are getting Network Error android.os.NetworkOnMainThreadException
For a thread to execute something on the background thread, you've to override its run method or you can create a Runnable and use it to create thread object
val networkThread = object: Thread() {
override fun run() {
try {
socket = Socket(ip, port)
} catch (e: java.lang.Exception) {
Log.e(TAG, "Network Error $e")
}
}
}
networkThread.start()
Related
I have method in class MyClassB which is triggered asynchronously from a method of MyClassA:
public void getProductCall()
{
new Thread(new Runnable() {
#Override
public void run() {
try {
productRequest = service.createS4ProductRequest(getRepriceItems());
//Below is a rest call to another system
String response = pricing.getS4ProductResponse(quote.getAssetQuoteNrAndVrsn(), productRequest);
//I'm using the below 2 lines to check from ClassA's method to see if this process has ended
setProductResponse(response);
productPriceProcessEnded=true;
} catch (Exception e) {
productPriceErrorOccured=true;
e.printStackTrace();
}
}
}).start();
}
This is the piece of code in MyClassA i used to check if the above method is complete.
for(int i=0;i<1000000000;i++)
{
if(!networkAsynCalls.isListPriceErrorOccured())
{
if(networkAsynCalls.isListPriceprocessEnded())
{
return networkAsynCalls.getListReponse();
}
else
{
Thread.sleep(250);
continue;
}
}
else
return null;
}
instead of using this random for loop can i use some inbuilt method or service pool or something ?
Because,
1) This thread on method is in another class
2) In class MyClassB i have few more methods like this, so i need to check the status of all the methods in MyClassA
Thanks for any help.
If I undestand what you're trying to do is dispatch some code to be ran asynchronously, then be able to wait until it is completed (successfully or failed). If that's the case, you should take a look at Futures.
Here is an example based on the Javadoc:
FutureTask<String> future =
new FutureTask<String>(new Callable<String>() {
public String call() {
// do stuff
return "result";
}});
This code creates an object "future" that can be invoked to execute searcher.search(target). At this point, the code is not executed at all. You simply have an object representing a computation that may be executed asynchronously. To do so, you'd call:
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(future);
This snippet created an Executor (which is a fixed pool of 5 threads), then handed over the future to it for execution. The executor will run the computation from Future asynchronously.
Future offers some methods (see the Javadoc) to wait until completion, cancel, check completion status, etc. For example,
String result = future.get();
will block, waiting for the result indefinitely. A get(10, TimeUnit.SECONDS) will wait for 10 seconds and if the future has not completed, throw.
I am trying to shutdown the application, whenever any Fatal
Error/Exception comes but before shut down the application my current
thread/task should complete, so I have written mainThread.join()
inside run(), its working fine when there is no exception. But whenever my
doTask() throwing exception that time join() waiting forever.
public class POC
{
public void doTask() throws Exception
{
throw new Exception("Fatal Error");
//throw new Exception("Fatal Error"); By commenting working fine.
}
public static void main(String[] args)
{
POC ob = new POC();
final Thread mainThread = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
try
{
System.out.println("Join() Start");
mainThread.join();
System.out.println("Join() End"); //Why this is not printing?
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
});
try
{
System.out.println("Before doTask()");
ob.doTask(); //User Defined Run()
System.out.println("After doTask()");
}
catch (Exception ex) // FATAL
{
System.err.println("Exception : " + ex.getLocalizedMessage());
System.exit(-1);
}
}
}
OutPut : 0
Before Run()
Exception : Fatal Error
Join() Start
Why System.out.println("Join() End"); is not printing?
You have a simple deadlock.
When you throw an exception, exception handler call System.exit(-1), which is blocking, see javadoc:
Terminates the currently running Java virtual machine by initiating its shutdown sequence
...
The virtual machine's shutdown sequence consists of two phases. In the first phase all registered #addShutdownHook shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish.
So main thread is waiting in System#exit call until all shutdown hook will be finished and your only shutdown hook blocks and waits until main thread will finish (which is waiting in System#exit ... GOTO 1).
One of my Runnable runs following code:
while(true) {}
I have tried wrapping that Runnable in Executor apis and then tried shutdown method. Tried thread.interrupt. but nothing works. I can not modify Runnable code. Any suggestions...
Check its interrupted flag:
while (!Thread.currentThread().isInterrupted()) {}
Most of the Executors interrupt worker threads on shutdownNow, so this gives you a tidy mechanism for a clean shutdown.
If you need to terminate the Runnable outside the context of an Executor, you'll need to give it a shutdown method that sets a flag.
final AtomicBoolean isShutdown = new AtomicBoolean();
public void shutdown() {
if (!isShutdown.compareAndSet(false, true)) {
throw new IllegalStateException();
}
}
#Override
public void run() {
while (!Thread.currentThread().isInterrupted() && !isShutdown.get()) {}
}
I'm trying to do some optimization in my code and would like to spawn a thread where I do a time consuming operation. During the implementation of that optimization I was running into an issue which was driving me crazy. I simplified the issue and created a test case for that specific issue: (I'm using SpringJUnit4ClassRunner so the transaction is properly started at the beginning of the testCRUD method)
Could someone help me understand why the foundParent is null in the thread ?
private Semaphore sema = new Semaphore(0, false);
private long parentId;
#Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);
parentDao.flush();
}
(new Thread(
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!
System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
})).start();
try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
=============================EDITED===================================
As per one comment suggestion, I created a threadManager bean which spawn the thread. Here is the code of the threadManager:
public class ThreadManager {
#Transactional(propagation=Propagation.REQUIRES_NEW)
public void executeTask(String Name, Runnable task) {
(new Thread(task, Name)).start();
}
}
Then in the previous test, instead of staring the thread manually, I just post it in the thread manager like this:
#Autowired private ParentDao parentDao;
#Autowired private ThreadManager threadManager;
private Semaphore sema = new Semaphore(0, false);
private long parentId;
#Test
public void testCRUD() {
//create
DBParent parent = null;
{
parent = new DBParent();
parentDao.persist(parent);
parentId = parent.getId();
assertTrue(parentId > 0);
parentDao.flush();
}
threadManager.executeTask("BG processing...",
new Runnable() {
public void run()
{
System.out.println("Start adding childs !");
DBParent foundParent = parentDao.findById(parentId);
assertTrue(foundParent != null); //ASSERTION FAILS HERE !!!!
System.out.println("Releasing semaphore !");
sema.release();
System.out.println("End adding childs !");
}
});
try {
System.out.println("Acquiring semaphore !");
sema.acquire();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
Unfortunately this doesn't work either !!! :-(
The transaction context is bound to the thread. So the code in the spawned thread doesn't run in the same transaction context as the code in the initial thread. So, due to transaction isolation (the I in ACID), the spawned thread doesn't see what the initial thread's transaction is inserting in the database.
You can bind Spring transaction to a new thread, to run transactions & Hibernate/JPA access in it. But this has to be a different TX and JPA/HB session from other threads.
Spring code for OpenSessionInViewFilter, is a reasonable an example of how to bind Hibernate session to Spring's TX management. You can strip this down to fairly minimal code.
See:
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
OpenSessionInViewFilter.doFilterInternal() -- this is where it actually binds it
TransactionSynchronizationManager.bindResource()
TransactionSynchronizationManager.unbindResource()
TransactionSynchronizationManager.getResource()
In one project (IIRC) I wrapped this functionality into a 'ServerThreadHb' class, to setup & save previous thread-bindings on construction -- with a restore() method to be called in a finally block, to restore previous bindings.
For your posted code sample, there isn't much point in running work on a separate thread -- since you synchronously wait for the work to be done. However I assume you were planning to remove that constraint & extend that functionality.
I have a windows service, which is executed regular intervals... Here is the code snippet:
protected override void OnStart(string[] args)
{
tickTack = new Timer(10000);
tickTack.Elapsed += new ElapsedEventHandler(tickTack_Elapsed);
tickTack.Start();
}
protected override void OnStop()
{
tickTack.Stop();
}
private void tickTack_Elapsed(object sender, ElapsedEventArgs e)
{
objProc = new Processing();
objProc.start();
}
In my start() method of Processing Class do my actual work like below.
public void start()
{
try
{
Process_Requests();
Process_Exports();
}
catch (Exception ex)
{
ErrorLogs.SaveError(ex, "");
}
}
How does the execution is happen when the execution done in a single thread??? For example, the first method takes time for execution then what about second method????
Now I want to call Process_request() and Preocess_export() methods. Each method should connect to multiple databases. In this situation, would I need to create new thread for each connection and do my work... I am not sure.
public void start()
{
try
{
#region
sqlConObjects = new List<SqlConnection>();
// Here i am getting multiple connection strings
List<string> conStrings = GetConnectionStrings();
foreach (string strCon in conStrings)
{
SqlConnection sqlCon = new SqlConnection(strCon);
sqlConObjects.Add(sqlCon);
}
foreach (SqlConnection sqlCon in sqlConObjects)
{
//sqlCon.Open();
Thread t = new Thread(ProcessRequest);
t.Start((object)sqlCon);
Thread t1=new Thread(ProcessExports);
t1.Start((object)sqlCon);
}
#endregion
}
catch (Exception ex)
{
ErrorLogs.SaveError(ex, "");
}
}
Can anyone please explain how to do this... is thread is created or no need??? How should the execution is happen if we are not creating a thread for each connection object.
Timer works on ThreadPool
From MSDN
The callback method executed by the timer should be reentrant, because it is called on ThreadPool threads. The callback can be executed simultaneously on two thread pool threads if the timer interval is less than the time required to execute the callback, or if all thread pool threads are in use and the callback is queued multiple times.
Also in your's code you don't keep reference to timer object and it will be collected.
As for me you should use ThreadPool. Createing a lot of threads is bad practice