Blocking code in java

Tech Tutorials

Tutorials and posts about Java, Spring, Hadoop and many more. Java code examples and interview questions. Spring code examples.

Friday, December 13, 2019

Blocking Methods in Java Concurrency

There are methods in Java that execute the task assigned without relinquishing control to other thread. In that case they have to block the current thread until the condition that fulfills their task is satisfied. Since these methods are blocking in nature so known as blocking methods.

A very relevant example of blocking methods in Java, which most of you would have encountered is read() method of the InputStream class. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.

Then there is accept() method of the ServerSocket class. This method listens for a connection to be made to this socket and accepts it and blocks until a connection is made.

Since this post is more about blocking methods from the Java multi-threading perspective so let’s have some example from there.

Examples of blocking methods in Java multi-threading

  • wait() method— Blocks the current thread until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.
  • sleep() method— Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds.
  • join() method— Where the current thread is blocked until all the other threads finish.
  • BlockingQueue and BlockingDeque interfaces— Starting Java 5 with the introduction of java.util.concurrent package blocking data structures which implements these two interfaces BlockingQueue and BlockingDeque have been added. Some of the examples are ArrayBlockingQueue, LinkedBlockingQueue and LinkedBlockingDeque.
  • put(E e)— Inserts the specified element into this queue, which will block if the space is full.
  • take()— Retrieves and removes element from the queue, waiting if necessary until an element becomes available.

Drawback of blocking methods

Though it is essential to block threads in order to have some synchronization on the execution order or the access on shared object but at the same time blocking threads may lead to suspension of multiple threads even waiting forever if not handled properly posing a serious threat to scalability and performance.

As example— If a thread holding the lock is waiting for some resource like I/O or delayed due to some other fault then other waiting threads will not make any progress.

Читайте также:  Python печать файла на принтере

Non-Blocking Data Structures

Java 5 has added many data structures in concurrency package that use non-blocking algorithm like atomic variables i.e. AtomicInteger, ConcurrentLinkedQueue or reduce the probability of blocking by using techniques like lock striping as used in ConcurrentHashMap.

Non-blocking I/O

Java NIO’s non-blocking mode in which an I/O operation will never block and may transfer fewer bytes than were requested or possibly no bytes at all from the Channel.

That’s all for this topic Blocking Methods in Java Concurrency. If you have any doubt or any suggestions to make please drop a comment. Thanks!

Источник

Implement a blocking function call in Java

What is the recommended / best way to implement a blocking function call in Java, that can be later unblocked by a call from another thread? Basically I want to have two methods on an object, where the first call blocks any calling thread until the second method is run by another thread:

public class Blocker < /* Any thread that calls this function will get blocked */ public static SomeResultObject blockingCall() < // . >/* when this function is called all blocked threads will continue */ public void unblockAll() < // . >> 

The intention BTW is not just to get blocking behaviour, but to write a method that blocks until some future point when it is possible to compute the required result.

3 Answers 3

latch = new CountDownLatch(1); 

If you’re waiting on a specific object, you can call myObject.wait() with one thread, and then wake it up with myObject.notify() or myObject.notifyAll() . You may need to be inside a synchronized block:

class Example < List list = new ArrayList(); // Wait for the list to have an item and return it public Object getFromList() < synchronized(list) < // Do this inside a while loop -- wait() is // not guaranteed to only return if the condition // is satisfied -- it can return any time while(list.empty()) < // Wait until list.notify() is called // Note: The lock will be released until // this call returns. list.wait(); >return list.remove(0); > > // Add an object to the list and wake up // anyone waiting public void addToList(Object item) < synchronized(list) < list.add(item); // Wake up anything blocking on list.wait() // Note that we know that only one waiting // call can complete (since we only added one // item to process. If we wanted to wake them // all up, we'd use list.notifyAll() list.notify(); >> > 

Not sure I would advocate wait() and notify() in new code — they are tricky to get right. (For example, in your code snippet, it is probably safer to use notifyAll() than notify()). See Joshua Bloch’s «Effective Java» item 69.

Читайте также:  View java lang illegalstateexception

also there are newer alternatives (ReentrantLock#newCondition with methods await() and signalAll()) which would should discourage the use of archaic wait/notify.

Источник

What exactly is a blocking method in Java?

The definition of a blocking method is very clear. There is still something that puzzles me. In a Java program, if I create a thread and try to take() from an empty BlockingQueue , that thread becomes in WAITING state according to the debugger. This is as expected. On the other hand, if I create a thread and try to call accept() method of ServerSocket class(This is also a blocking code according to the JavaDoc), I see that this thread always in RUNNING state. I am expecting a blocking method to be parked with monitors in Java. If a method is blocking like ServerSocket::accept , how come this method does not progress accept line and still have the status of RUNNING?

I would expect if a blocking method does not return, thread state should be WAITING, BLOCKED?Can a blocking method block the thread and state can be RUNNING?(Like ServerSocket::accept)

I’d say a blocking method is one that waits for something else to happen before it can continue. For example, taking from a blocking queue waits for another thread to put something in the queue. Accepting a socket connection waits for some external process/system to try and connect. Reading from an input stream waits for data to be available. All those examples are different from a method simply taking a while to compute something.

2 Answers 2

There’s the concept of ‘a blocking call’ / ‘a blocking method’, as one might use in conversation, or as a tutorial might use, or even as a javadoc might use it.

Then there is the specific and extremely precisely defined java.lang.Thread state of BLOCKING .

The two concepts do not align, as you’ve already figured out with your test. The BLOCKING state effectively means ‘blocking by way of this list of mechanisms that can block’ (mostly, waiting to acquire a monitor, i.e. what happens when you enter a synchronized(x) block or try to pick up again from an x.wait() call: In both cases the thread needs to become ‘the thread’ that owns the lock on the object x is pointing at, and if it can’t do that because another thread holds it, then the thread’s state becomes BLOCKING.

This is spelled out in the javadoc. Here’s the quote:

A thread that is blocked waiting for a monitor lock is in this state.

(‘monitor lock’ is JVM-ese for the mechanism that synchronized and obj.wait/notify/notifyAll work with, and nothing else).

Читайте также:  Document

Keep reading the full javadoc of that page, as the detailed descriptions of these states usually spell out precisely which methods can cause these states.

This lets you figure out that if you write this code:

then that thread goes through these states, in the worst case scenario)

  • RUNNING -> BLOCKED (another thread is in a synchronized(foo) block already).
  • BLOCKED -> RUNNING (that other thread is done)
  • RUNNING -> WAITING (obj.wait() is called, now waiting for a notify)
  • WAITING -> BLOCKED (we’ve been notified, but the thread still cannot continue until that monitor is picked up again, that’s how wait and notify work).
  • BLOCKED -> RUNNING (got the lock on foo)

So why is my I/O thing on RUNNING then?

Unfortunately, I/O-related blocking is highly undefined behaviour.

However, I can explain a common scenario (i.e. what most combinations of OS, hardware, and JVM provider end up doing).

The reason for the undefined behaviour is the same reason for the RUNNING state: Java is supposed to run on a lot of hardware/operation system combos, and most of the I/O is, in the end, just stuff that java ‘farms out’ to the OS, and the OS does whatever the OS is going to do. Java is not itself managing the state of these threads, it just calls on the OS to do a thing, and then the OS ends up blocking, waiting, etc. Java doesn’t need to manage it; not all OSes even allow java to attempt to update this state, and in any case there’d be no point whatsoever to it for the java process, it would just slow things down, and add to the pile of ‘code that needs to be custom written for every OS that java should run on’, and that’s a pile you’d prefer remain quite small. The only benefit would be for you to write code that can programatically inspect thread states. and that’s more a job for agents, not for java code running inside the same VM.

But, as I said, undefined, mostly. Don’t go relying on the fact that x.get() on a socket’s InputStream will keep the thread in RUNNING state.

Similar story when you try to interrupt() a thread that is currently waiting in I/O mode. That means the I/O call that is currently waiting for data might exit immediately with some IOException (not InterruptedException, though, that is guaranteed; InterruptedException is checked, InputStream.read() isn’t declared to throw it, therefore, it won’t) — or, it might do nothing at all. Depends on OS, java version, hardware, vendor, etc.

Источник

Оцените статью