How does start() method invoke threads in Java? - multithreading

With an example code shown to create a thread by invoking start() method of java.lang.Thread class,
public class MyThread extends Thread{
public void run(){
//code to run goes here
}
}
MyThread myThread = new MyThread();
myThread.start();
I understand that a second thread gets created in addition to main thread. This second thread performs the work given in run() method.
So, the JVM process is running this code with two user level threads.
Sun J2SE 5.0 is the environment running on Windows 2008/2012 boxes.
My question:
How many kernel level threads does OS dedicate for this JVM process? Does each user level thread map to a separate kernel thread? It is important to know this info, before running the enterprise application with configurable number of threads on destination OS platform.

Related

How to pass on a traceId from gRPC's context to another thread/threadPool?

I am using grpc-java and have 3 services, A, B and C. I call service A and then service A calls B and C. I am using Hystrix in the calls to B and C. C in turn spawns another thread to call another service.
I have ClientInterceptors and ServerInterceptors which passes around the traceId. I can see the traceIds in the Context and logs as long as it is a gRPC worker thread but lose them when the call moves to another thread - RxIoScheduler thread or Hystrix thread. How do I pass the traceId around between requests on different threads and between different executor service and thread pools?
While it is possible to propagate in a fine-grained way (like executor.execute(Context.current().wrap(runnable))), you should try to integrate Context propagation into cross-thread work transfer. For many applications, that'd be as simple as wrapping the "main" executor as soon as it is created:
executor = Context.currentContextExecutor(executor);
// executor now auto-propagates
Do that once at the beginning of your application and then you mostly stop worrying about propagation.
But applications will vary. For example, applications that create Threads directly should probably make a ThreadFactory that propagates the calling thread's Context to the Thread:
class PropagatingThreadFactory implements ThreadFactory {
private final ThreadFactory delegate;
public PropagatingThreadFactory(ThreadFactory d) {delegate = d;}
#Override public Thread newThread(Runnable r) {
return delegate.newThread(Context.current().wrap(r));
}
}

QT - Show Widget without blocking his GUI

I want to show a widget for displaying an animated loading gif while another function (pthread) computes a task.
I have tried to subclass my widget with a QThread class, and implemented the method run() where I call the method show(). However, my widget GUI froze.
How can I launch a widget where the GUI is processed separately?
You can't have widgets running on anything except the main thread.
Also, unless you're wanting to change how Qt handles threads, you should not be inheriting from QThread.
Instead, create a worker object that inherits from QObject and move that to the new thread. You can read how to really use QThread here.
Your worker object can then be moved to another thread, do its computation and communicate to the Gui widgets, on the main thread, via signals and slots.
For example, here's a brief outline of a worker class: -
class Worker : public QObject
{
Q_OBJECT
signals:
void finished();
void displayWidget();
private slots:
void run();
}
QThread pThread = new QThread;
Worker pObject = new Worker;
// move the pObject to the thread
pObject->moveToThread(pThread);
You can then control the thread with signals and slots.
// assuming you've added a run slot function to the Consumer class
connect(pThread, SIGNAL(started()), pObject, SLOT(run()));
connect(pObject, SIGNAL(finished()), pThread, SLOT(quit()));
connect(pObject, SIGNAL(finished()), pObject, SLOT(deleteLater()));
// Note the thread cleans itself up here, but if the app is quitting,
// waiting on the thread to finish may be required instead
connect(pThread, SIGNAL(finished()), pThread, SLOT(deleteLater()));
And start the thread: -
pThread->start();
Used this way, it also enables multiple objects to be moved to a single new thread, rather than creating a new thread per object instance.
So now, for example, if you wanted to display a widget at some point during the processing in the worker object, you'd emit its displayWidget() signal, having previously connected it to the Widget's show() slot.
QWidget* pWidget = new QWidget(parent); // assumes parent is initialized
// using Qt 5 connect call
connect(pWorker, &Worker::displayWidget, pWidget, &Widget::show);
You can't use QWidget (nor any derived classes) directly from threads other than the GUI thread. All you can do directly is to use a QImage owned by the worker thread and paint on it directly from that thread. Here, directly means that you are simply calling methods of objects.
What you need is a way to execute show() not directly in the invoking thread, but indirectly within the GUI thread's context. This is quite simple since QWidget::show() is a slot. Thus, from your computation thread, simply do:
QMetaObject::invokeMethod(widget, "show");
That's all. The implementation of invokeMethod will determine that widget lives in a different thread, and will automatically choose the QueuedConnection method of call delivery. Internally, it will post a QMetaCallEvent to widget. The widget's QObject::event method will act on the event and place the call to the show method. This will happen in the GUI thread.
You can use the same approach to set QProgressBar, for example:
int value = ...;
QMetaObject::invokeMethod(progressBar, "setValue", Q_ARG(int, value));

Qt "no matching function for call to connect", modifying Qt Fortune Threaded Server example

I am trying to modify the Qt Fortune Threaded Server example to read text from the connection and then echo it back. I defined tcpSocket in my FortuneThread.h file as follows:
QTcpSocket tcpSocket;
My new run function for the thread looks as follows:
void FortuneThread::run()
{
if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
emit error(tcpSocket.error());
return;
}
connect(&tcpSocket, SIGNAL(readyREAD()), this, SLOT(readCommand()) );
}
Which compiles and runs, but once I connect I get this error (referring to the connect line):
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpSocket(0x1eeb920), parent's thread is QThread(0x1bb3f90), current thread is FortuneThread(0x1eeb8f0)
QObject::connect: No such signal QTcpSocket::readyREAD() in ../fortune/fortunethread.cpp:60
Can someone explain the cause to me? Since tcpSocket is defined inside the FortuneThread class (which is run as a separate thread), and "this" refers to FortuneThread, I assume both objects are inside the thread? How to fix this?
Your socket object has been created in the main thread, but you're accessing it from a different thread. You need to create it inside of the thread's run() method. The location where the socket is defined doesn't matter. It will be created from the main thread when the C++ runtime library is doing static object initialization.
QTcpSocket * tcpSocket;
...
void FortuneThread::run() {
tcpSocket = new QTcpSocket;
...
}
I agree with Kuba Ober. You should read that great guide about Qt threads, objects and events. In particular, section called Signals and slots across threads. Authors recommends split controller and work parts into different essences.
Second issue in your code — case sensitive signal name. Change it to readyRead.
A problem with the Qt Fortune Threaded Server example is the way in which it uses threads. As the developers of Qt say, "You're doing it wrong"
The issue is the inheritance of QThread. The QThread class is not actually a thread, but a thread controller class and the only reason to inherit this, is if you want to change the behaviour of controlling threads.
The problem you're seeing is due to thread affinity; which thread an object belongs to.
If a thread is inherited like this: -
class FortuneThread : public QThread
{
Q_OBJECT
private:
QTcpSocket tcpSocket;
};
An object of FortuneThread is then instantiated from the main thread: -
FortuneThread* ft = new FortuneThread(parent);
The thread affinity for the thread and the objects it has instantiated (tcpSocket) is now the main thread, so the tcpSocket is running on the main thread, which is what the error is stating. At the point the run function is called, the connect is coming from the FortuneThread, but the tcpSocket is on the main thread.
The better way to solve this is to create your class, derived from QObject and move it to the thread: -
// Inherit from QObject, not QThread
class FortuneSocket : public QObject
{
Q_OBJECT
public slots:
void Run();
private:
QTcpSocket tcpSocket;
};
QThread* pThread = new QThread(parent);
FortuneSocket* pFortune = new FortuneSocket(parent);
connect(pThread, &QThread::started, pFortune, &FortuneSocket::Run); // Qt5 connect style
// move the fortune socket to the thread: -
pFortune->moveToThread(pThread);
Now, when you start the thread with pThread->start(), the FortuneSocket object and all of its members are running on the new thread.
Using threads this way also means that you can move multiple objects to a single thread, rather than having one object per thread. Note that creating more threads than CPU cores is pointless!
Finally, there's a more in-depth article on how to use QThread, here.

Java EE scheduled task and forced task

I'm working on a Java EE Web application.
I've developed a Scheduled Batch using #WebListener annotation:
#WebListener
public class BatchServlet implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
context = sce.getServletContext();
schedulerEngine = Executors.newSingleThreadScheduledExecutor();
schedulerEngine.scheduleAtFixedRate(new MyThread(), 0, 300, TimeUnit.SECONDS);
}
public class MyThread implements Runnable {
#Override
public void run() {
...... //my business logic
}
and it works correctly.
But, for my purpose, I need to force the MyThread() batch on demand, for example, when I received a particular request within a Servlet. Obviosly I can call the MyBatch thread separately, but I was wondering that there are some best practices to perform this operation.
There are a couple of options: create a regular thread pool (with multiple threads) and just put tasks on the executor queue whenever they come in.
If you need more fine-grained control, you can share something like a concurrent queue between the servlet and the one thread that you have. Let this thread read from the queue, it will block automatically when the queue is empty.
Then your servlet can put work on this queue, if the thread happened to be blocked on getting an item it will automatically wake up.
You might wanna look up the "producer-consumer" pattern. There is a lot of literature about this.

Is there a way to detect when a QT QRunnable object is done?

Is there a way to detect when a QT QRunnable object is done? (Other than manually creating some signalling event at the end of the run() method.)
You can simply use QtConcurrent to run the runnable and use a QFuture to wait for finished.
#include <QtConcurrentRun>
class MyRunnable : public Runnable{
void run();
}
in order to run and wait for it you can do the following
//create a new MyRunnable to use
MyRunnable instance;
//run the instance asynchronously
QFuture<void> future = QtConcurrent::run(&instance, &MyRunnable::run);
//wait for the instance completion
future.waitForFinished();
Qtconcurrent::run will start a new thread to execute method run() on instance and immediately returns a QFuture that tracks instance progress.
Notice however that using this solution you are responsable to keep instance in memory during the execution.
There might be, or you might have to go a slight bit higher-level. The QFuture and QFutureWatcher classes are designed to work with Qt's Concurrent framework, and the QFutureWatcher class has a signal when the item it is watching has finished.
You can add your own SIGNAL which gets emitted as the last thing that your run() method does. Then simply connect it to coreesponding SLOT right before calling connect(...);

Resources