So let's say I'm creating and starting a bunch of threads in a for loop, that is being executed in the run method of a launcher thread. Let's also say that I want to be able to interrupt the launcher thread and all threads that the thread has created, and I do this through a button.
So something like this -
try{
for(int i = 0; i < n;i++){
Worker currThread = new Worker(someArgs);
workerThreads.add(currThread);
currThread.start();
}
} catch (InterruptedException e){
e.printStackTrace();
}
BUTTON-
public void actionPerformed(ActionEvent arg0) {
List<Worker> threads = launchThread.getWorkerThreads();
for(int i = 0; i < threads.size();i++){
threads.get(i).interrupt();
}
launchThread.interrupt();
}
Now, let's say that I want to make it so that the interrupts cannot occur at the same time as thread creation. I think a way to do this would be to construct a dummy object and put both pieces of code inside a lock
synchronized(dummyObject){
//thread creation or interruption code here (shown above)
}
Will this way work? I ask because I'm not sure how to test to see if it will.
Start the threads separately from creating them.
for(int i = 0; i < n; i++) {
Worker currThread = new Worker(someArgs);
workerThreads.add(currThread);
}
// later
for (Worker w : workerThreads) {
w.start();
}
If that's still not enough, your dummyObject synchronization should work just fine.
// You probably need to make this a (private final) field
Object lock = new Object();
// later
synchronized (lock) {
for(int i = 0; i < n; i++) {
Worker currThread = new Worker(someArgs);
workerThreads.add(currThread);
w.start();
}
}
// later still
public void actionPerformed(ActionEvent arg0) {
synchronized (lock) {
// interruption code here
}
}
The concept of synchronization remains the same however complicated are the underlying operations to be executed.
As you specified, there are two types of mutually exclusive tasks (thread creation and interruption). So locking is pretty much the canonical tool for the job.
Related
I am fetching thousands of URLs and parsing tables from it using parseDocument(doc). It would take hours to parse all tables, so I wanted to use threads to parse a lot of them at the same time, but don't know to do it.
The code below is a for loop that I need to use threads on:
for(int i = 0; i < urlList.size(); i++) {
Document doc = Jsoup.connect(urlList.get(i)).get();
reader.add(parseDocument(doc));
}
for(int i = 0; i < urlList.size(); i++) {
Thread t = new Thread(new Runnable() {
public void run() {
try {
//parsedocument( urlList.get(i))
} catch (Exception e) { //Catching exeptions
e.printStackTrace();
}
}
});
t.start();
}
We create a thread variable called 't' that we could use. For example, can wait for it to finish using .Join(). A thread requires a run void where the actual operations will execute, this is because it uses something called "runnable" which is an interface that needs that Run method. Here you would parse the document. Finally, we start the thread by call t.start().
In a certain part of a Java code that i am working, i need to place a timer inside a run() method. Each thread will execute all code inside run(). But i need to start measuring after block (1) and before block of code (2) so the timer needs to be triggered there.
for (int i = 0; i < total_threads-1; i++){
final int id = i+1;
th[i] = new Thread(new Runnable() {
public final void run(){
/* ... block of code (1) executed by multiple threads ... */
/* How can i start this counter only once? */
final long begin = System.currentTimeMillis();
/* ... another block of code (2) executed by multiple threads i need to measure!!! ... */
}
});
th[i].start();
}
for(int i = 0 ; i < total_threads-1 ; i++) {
try {
th[i].join();
}
catch (InterruptedException e) {}
}
final long end = System.currentTimeMillis();
System.out.println((end-begin) / 1000.0);
But all the threads will have their own begin variable and start the counter which is a problem because System.currentTimeMillis() should be triggered once and not by many threads.
I probably could separate the code of run() in two different parallel regions but would imply creating the threads twice which would be unacceptable (in terms of performance).
There is a similar technique of OpenMP directive #pragma omp master for Java using Java threads?
How can i measure the time correctly here?
You can check the thread ID to execute prefer line once:
if (id == YOUR_THREAD_ID)
{
begin = System.currentTimeMillis();
}
The simplest way would just be to record the time in the master thread (i.e. the thread which creates all the children) instead of in the children themselves.
But if you really want to start the timer in the children (maybe there's some expensive setup?), you could use a Guava StopWatch object.
The code would look something like:
StopWatch timer = StopWatch.createUnstarted();
for (int i = 0; i < total_threads-1; i++){
final int id = i+1;
th[i] = new Thread(() -> {
/* ... block of code (1) executed by multiple threads ... */
try {
synchronized (timer) {
timer.start();
}
} catch (IllegalStateException e) {
// ignore; the watch is already started
}
/* ... another block of code (2) executed by multiple threads i need to measure!!! ... */
});
th[i].start();
}
for(int i = 0 ; i < total_threads-1 ; i++) {
try {
th[i].join();
} catch (InterruptedException e) {}
}
timer.stop();
System.out.println(timer.elapsed(TimeUnit.SECONDS));
I'm calling interrupt on day 370, and then calling it again during the catch block during the run method of the other classes. I also have a while condition that loops while thread is not interrupted, but for some reason, it's not working, and I have no idea why. I know I can use variable flag instead, but I want to try making interrupt() works. I've look at multiple sites already, but none seems to work for me. Please help.
public class Elf implements Runnable {
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// wait a day
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
public class Main {
public static void main(String args[]) {
Scenario scenario = new Scenario();
// create the participants
// Santa
scenario.setSanta( new Santa(scenario) );
Thread th = new Thread(scenario.getSanta());
th.start();
// The elves: in this case: 10
for (int i = 0; i != 10; i++) {
Elf elf = new Elf(i + 1, scenario);
scenario.getElves().add(elf);
th = new Thread(elf);
th.start();
}
// The reindeer: in this case: 9
for (int i = 0; i != 9; i++) {
Reindeer reindeer = new Reindeer(i + 1, scenario);
scenario.getReindeers().add(reindeer);
th = new Thread(reindeer);
th.start();
}
// now, start the passing of time
for (int day = 1; day < 500; day++) {
// wait a day
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// turn on December
if (day > (365 - 31)) {
scenario.setDecember(true);
}
// interrupt flag is set here
if (day == 370) {
th.interrupt();
}
// print out the state:
System.out.println("*********** Day " + day
+ " *************************");
scenario.getSanta().report();
for (Elf elf : scenario.getElves()) {
elf.report();
}
for (Reindeer reindeer : scenario.getReindeers()) {
reindeer.report();
}
}
}
}
I've only included the Elf class here, but the other classes are of the same structure with almost the same code in it. Right now the program finishes with the red square (terminate button) still lit, and I read that that is an indication that there are still threads running. I'm not sure why it's not stopping.
A variable declared as Thread th is a reference to an object of type Thread. It's only a reference to one object. This is true, by the way, for all types, not just thread.
Whenever you put a new value into a variable, it no longer refers to the old value[1].
Thus th.interrupt() in your code will just interrupt the last thread that you assigned to it - the most recent reindeer thread.
If you want to interrupt all the threads, you'll need to keep a reference to all the threads.
A basic solution
A simple way to do this would be to use a list of Thread:
List<Thread> allThreadsToInterrupt = new ArrayList<>();
When you create a thread, you do
th = new Thread(...);
allThreadsToInterrupt.add(th);
And then at the end you can do:
for ( Thread th: allThreadsToInterrupt ) {
th.interrupt();
}
Using a ThreadGroup
But in fact, Java has an existing class that helps you with this - the ThreadGroup class. You can do something like:
ThreadGroup elfThreads = new ThreadGroup("Elf Threads");
ThreadGroup reindeerThreads = new ThreadGroup( "Reindeer Threads" );
Now, whenever you create a thread, you should create it with a thread group:
Instead of:
th = new Thread(elf);
Use:
th = new Thread(elfThreads,elf);
Then at the end, to interrupt all the elves, you can run:
elfThreads.interrupt();
This would automatically call interrupt() on all threads that belong to the group.
Of course, you can just create one big group, but I demonstrated separating the elves and the reindeer, in case you will need them to be interrupted separately.
[1] In most cases replacing an old reference, which was the only reference to an object, with a new reference will cause the old object to be eligible for garbage collection, but threads are a little different, because if they have been started, there is a second reference to them from the current thread group (because that's the default when you don't give a thread group when you create a thread), which means that they will not be garbage-collected and they will run properly until they complete.
I have two threads in my java programme, one is main thread and other thread is thread A which is spawned in main thread. now i want main thread to start thread A and wait till thread A has executed some part of its code in run method and thread A should suspend itself. main thread should then start running, run few lines of code and then again thread A should start from where it has stopped and vice versa. this should happen for n number of times.
I am trying as belows:
Thread A class:
public class ThreadA implements Runnable {
boolean suspended = false;
boolean stopped = false;
synchronized void stop() {
stopped = true;
suspended = false;
notify();
}
synchronized void suspend() {
suspended = true;
}
synchronized void resume() {
suspended = false;
notify();
}
void job() throws InterruptedException {
for (int i = 0; i < 5; i++)
synchronized (this) {
System.out.println("performing job.");
suspend();
while (suspended) {
notify();
suspended = false;
}
}
}
#Override
public void run() {
try {
job();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MainThread:
public class MainThread {
public static void main(String[] args) throws InterruptedException {
ThreadA a1=new ThreadA();
Thread t1=new Thread(a1);
synchronized (t1) {
t1.start();
for (int i = 0; i < 5; i++) {
t1.wait();
System.out.println("perform some action");
a1.resume();
}
}
}
}
Expected output:
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
Actual output:
performing job.
performing job.
performing job.
performing job.
performing job.
perform some action
I don't know why the whole for loop is getting executed in Thread A even when i've issued a notify() signal in job method.
You have two bugs here.
The first is that you are synchronizing and notifying different objects. Try this modified main, I changed synchronized (t1) to synchronized (a1) and t1.wait() to a1.wait().
public static void main(String[] args) throws InterruptedException {
ThreadA a1=new ThreadA();
Thread t1=new Thread(a1);
synchronized (a1) { // CHANGED FROM t1 to a1
t1.start();
for (int i = 0; i < 5; i++) {
a1.wait(); // CHANGED FROM t1 to a1
System.out.println("perform some action");
a1.resume();
}
}
}
The second bug is in the job() method, it calls notify() but not wait(). Here is a fixed version:
void job() throws InterruptedException {
for (int i = 0; i < 5; i++)
synchronized (this) {
System.out.println("performing job.");
suspend();
while (suspended) {
notify();
suspended = false;
wait(); // ADDED
}
}
}
The output from my test run is
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
performing job.
perform some action
Here is more simplified way
public class TwoThread {
public static void main(String[] args) throws InterruptedException {
ThreadA a1 = new ThreadA();
Thread t1 = new Thread(a1);
synchronized (a1) {
t1.start();
for (int i = 0; i < 5; i++) {
a1.wait();
System.out.println("perform some action " + i);
a1.notify();
}
}
}
}
public class ThreadA implements Runnable {
boolean suspended = false;
boolean stopped = false;
void job() throws InterruptedException {
for (int i = 0; i < 5; i++)
synchronized (this) {
System.out.println("performing job. " + i);
notify();
wait();
}
}
public void run() {
try {
job();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
To communicate between two threads only:
You do not need synchronized
You do not need locks
You do not need CAS (Compare And Swap). (Neither weak or strong)
You do not need setOpaque, setVolative nor setRelease
You just need VarHandle barrier (in Java).
Java VarHandle
The only requirement is ordered memory access
Here is a reasonably good article.
Synchronizing without Locks and Concurrent Data
Structures
In my daily work, I use variants of Dekker's and Peterson's algorithm
for asynchronous multi-threaded processing of web requests, sharing connection pools and collecting logs from cloud application with minor impact on performance
compared to the single thread un-contended performance.
Occasionally, I have to use setOpaque and getOpaque,
with VarHandle.loadLoadFence() and VarHandle.storeStoreFence()
to ensure ordered memory access and that is all you would need.
In my view the weak CAS is the furthers I would go,
as anything else I see as a violation of the multi-core CPU architecture.
However, unless you have an in-depth understanding of the actual
hardware that you are using and memory ordering constructs
used at the micro-instruction level, I suggest you use
standard Java concurrent locks, as they are the best
and optimal for general-purpose solutions.
To achieve, 10 x performance boost over the conventional CAS algorithms,
you need to make very stable layout of all shared objects in memory
and to strictly define which threads can read
and which can write to each variable and in which order.
You will need to consider the side effect on the CPU cache
of all memory loads and stores, and then to get these
to work in your advantage on the specific platform
that you are targeting. You will end up with
quite complex algorithms, but unbeatable performance.
You should explore the LMAX Disruptor library
as it has the open source library that implements many of these concepts
like ring-buffers and single thread can write to each variable.
LMAX Disruptor User Guide
Yet, I still see this as the the conservative approach to concurrency.
My current standard is to have algorithm that tolerate racing
and discard data and repeat processing if they detect racing condition.
I use the state embeded counters, indexes, flags and hashes,
to detect thread collision and chose thread that will give up
and use another memory structure for its operation.
However, due to thread focused memory structures and
optimized reference sharing these occur rarely (like one in 1 million)
Yet, if you have good understanding of CPU cache operations
and any specialized platform instruction you can get CPU
cache to work in your advantage and execute reads and writes,
and sharing of cache lines between cores, as a side effect
of your instructions without you having to explicitly issue
commands to do this.
BTW, the NodeJS (V8) engine was an attempt to minimize contention and locking by having a single thread event loop to distribute events to all other I/O and utility library threads, so they do not have to compete between themselves for access to events and shared memory.
As you can see, NodeJS had great success,
and if we are talking about the special purpose algorithms
you can take it even further.
NodeJS architecture
Happy reading.
There is little reason to synchronize multiple threads if one threads waits while another does its thing. One could use Executors to get the same result with less work and still got the feeling that one is playing with the threads.
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
for(int i = 0; i<5;i++) {
executor.submit(new PrintTask("performing job."));
executor.submit(new PrintTask("perform some action"));
}
executor.shutdown();
}
private static class PrintTask implements Runnable {
private String string;
public PrintTask(String string) {
this.string = string;
}
#Override
public void run() {
System.out.println(string);
}
}
}
I have always thought that synchronizing the run method in a java class which implements Runnable is redundant. I am trying to figure out why people do this:
public class ThreadedClass implements Runnable{
//other stuff
public synchronized void run(){
while(true)
//do some stuff in a thread
}
}
}
It seems redundant and unnecessary since they are obtaining the object's lock for another thread. Or rather, they are making explicit that only one thread has access to the run() method. But since its the run method, isn't it itself its own thread? Therefore, only it can access itself and it doesn't need a separate locking mechanism?
I found a suggestion online that by synchronizing the run method you could potentially create a de-facto thread queue for instance by doing this:
public void createThreadQueue(){
ThreadedClass a = new ThreadedClass();
new Thread(a, "First one").start();
new Thread(a, "Second one, waiting on the first one").start();
new Thread(a, "Third one, waiting on the other two...").start();
}
I would never do that personally, but it lends to the question of why anyone would synchronize the run method. Any ideas why or why not one should synchronize the run method?
Synchronizing the run() method of a Runnable is completely pointless unless you want to share the Runnable among multiple threads and you want to sequentialize the execution of those threads. Which is basically a contradiction in terms.
There is in theory another much more complicated scenario in which you might want to synchronize the run() method, which again involves sharing the Runnable among multiple threads but also makes use of wait() and notify(). I've never encountered it in 21+ years of Java.
There is 1 advantage to using synchronized void blah() over void blah() { synchronized(this) { and that is your resulting bytecode will be 1 byte shorter, since the synchronization will be part of the method signature instead of an operation by itself. This may influence the chance to inline the method by the JIT compiler. Other than that there is no difference.
The best option is to use an internal private final Object lock = new Object() to prevent someone from potentially locking your monitor. It achieves the same result without the downside of the evil outside locking. You do have that extra byte, but it rarely makes a difference.
So I would say no, don't use the synchronized keyword in the signature. Instead, use something like
public class ThreadedClass implements Runnable{
private final Object lock = new Object();
public void run(){
synchronized(lock) {
while(true)
//do some stuff in a thread
}
}
}
}
Edit in response to comment:
Consider what synchronization does: it prevents other threads from entering the same code block. So imagine you have a class like the one below. Let's say the current size is 10. Someone tries to perform an add and it forces a resize of the backing array. While they're in the middle of resizing the array, someone calls a makeExactSize(5) on a different thread. Now all of a sudden you're trying to access data[6] and it bombs out on you. Synchronization is supposed to prevent that from happening. In multithreaded programs you simply NEED synchronization.
class Stack {
int[] data = new int[10];
int pos = 0;
void add(int inc) {
if(pos == data.length) {
int[] tmp = new int[pos*2];
for(int i = 0; i < pos; i++) tmp[i] = data[i];
data = tmp;
}
data[pos++] = inc;
}
int remove() {
return data[pos--];
}
void makeExactSize(int size) {
int[] tmp = new int[size];
for(int i = 0; i < size; i++) tmp[i] = data[i];
data = tmp;
}
}
Why? Minimal extra safety and I don't see any plausible scenario where it would make a difference.
Why not? It's not standard. If you are coding as part of a team, when some other member sees your synchronized run he'll probably waste 30 minutes trying to figure out what is so special either with your run or with the framework you are using to run the Runnable's.
From my experience, it's not useful to add "synchronized" keyword to run() method. If we need synchronize multiple threads, or we need a thread-safe queue, we can use more appropriate components, such as ConcurrentLinkedQueue.
Well you could theoretically call the run method itself without problem (after all it is public). But that doesn't mean one should do it. So basically there's no reason to do this, apart from adding negligible overhead to the thread calling run(). Well except if you use the instance multiple times calling new Thread - although I'm a) not sure that's legal with the threading API and b) seems completely useless.
Also your createThreadQueue doesn't work. synchronized on a non-static method synchronizes on the instance object (ie this), so all three threads will run in parallel.
Go through the code comments and uncomment and run the different blocks to clearly see the difference, note synchronization will have a difference only if the same runnable instance is used, if each thread started gets a new runnable it won't make any difference.
class Kat{
public static void main(String... args){
Thread t1;
// MyUsualRunnable is usual stuff, only this will allow concurrency
MyUsualRunnable m0 = new MyUsualRunnable();
for(int i = 0; i < 5; i++){
t1 = new Thread(m0);//*imp* here all threads created are passed the same runnable instance
t1.start();
}
// run() method is synchronized , concurrency killed
// uncomment below block and run to see the difference
MySynchRunnable1 m1 = new MySynchRunnable1();
for(int i = 0; i < 5; i++){
t1 = new Thread(m1);//*imp* here all threads created are passed the same runnable instance, m1
// if new insances of runnable above were created for each loop then synchronizing will have no effect
t1.start();
}
// run() method has synchronized block which lock on runnable instance , concurrency killed
// uncomment below block and run to see the difference
/*
MySynchRunnable2 m2 = new MySynchRunnable2();
for(int i = 0; i < 5; i++){
// if new insances of runnable above were created for each loop then synchronizing will have no effect
t1 = new Thread(m2);//*imp* here all threads created are passed the same runnable instance, m2
t1.start();
}*/
}
}
class MyUsualRunnable implements Runnable{
#Override
public void run(){
try {Thread.sleep(1000);} catch (InterruptedException e) {}
}
}
class MySynchRunnable1 implements Runnable{
// this is implicit synchronization
//on the runnable instance as the run()
// method is synchronized
#Override
public synchronized void run(){
try {Thread.sleep(1000);} catch (InterruptedException e) {}
}
}
class MySynchRunnable2 implements Runnable{
// this is explicit synchronization
//on the runnable instance
//inside the synchronized block
// MySynchRunnable2 is totally equivalent to MySynchRunnable1
// usually we never synchronize on this or synchronize the run() method
#Override
public void run(){
synchronized(this){
try {Thread.sleep(1000);} catch (InterruptedException e) {}
}
}
}