Concurrent access of String variable in java - java

If multiple threads are triggered does String variable (status) need to be synchronized?
class Request{
String status;
....// Some other variables used in thread
}
class Test{
public static void main(String[] args){
Requesr r = new Request();
List<Future> list= new ArrayList<Future>();
ExecutorService pool= Executors.newFixedThreadPool(10);
for(String input : inputList){
if(!"failed."equals(r.status)){
RequestHandler request = new RequestHandler(input,r);
Future f = pool.submit(request);
list.add(f);
}else{
//fail the job and return;
}
}
for (Future fTemp : list) {
if (fTemp.get() == null) {
// Task completed
}
}
}
}
class RequestHandler extends Runnable{
Map<String,String> input;
Requesr r;
RequestHandler(Map<String,String> input, Request r ){
this.input=input;
this.r = r;
}
#Override
public void run() {
if(!"failed".equals(r.status)){
try{
//some logic
}catch(Exception e){
r.Status = "failed";//status is assigned a value only here
}
}
}
}
Does status need to be synchronized for it to be visible in the Test class for loop and in other threads?
As mentioned below in comments I will use Future objects and cancel the running threads.
My doubt is whether above code works without synchronization logic. If it doesn't how can we add synchronization logic in this case?

The variable should probably be declared volatile. Else it may happen that a thread updates the value to "failed", but the main thread never sees this update. The reasons are explained here:
http://etutorials.org/Programming/Java+performance+tuning/Chapter+10.+Threading/10.6+Atomic+Access+and+Assignment/
It's possible (depending on what the triggering code does) that this is unnecessary, but it's not worth taking the risk.

Related

Java delay return value

I have a situation where I read data from a YAML file that is important for the application because it is used in several classes. Here is my code:
public class CredentialsReader {
private UserCredentials credentials;
private boolean isReading = false;
public CredentialsReader() {
}
public void readCredentials() {
Runnable readerTask = new Runnable() {
#Override
public void run() {
isReading = true;
parseCredentials();
isReading = false;
System.err.println("Parsed credentials");
}
};
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
service.scheduleAtFixedRate(readerTask, 0, 60, TimeUnit.SECONDS);
}
private void parseCredentials() {
final File f = new File("/home/dev/IdeaProjects/server/src/main/resources/credentials.yaml");
try {
UserCredentials userCredentials = new ObjectMapper().readValue(f, UserCredentials.class);
this.credentials = userCredentials;
System.out.println(this.credentials.getUsername() + ", " + this.credentials.getPassword());
} catch (IOException e) {
e.printStackTrace();
}
}
public UserCredentials getCredentials() { return this.credentials; }
}
As you see, I read the data every minute and my question is:
Can I delay the return value of getCredentials, so when the method is called I check if isReading is true and then delay the return so I can guarantee that a caller will always get the actual state of the yaml file?
I think there are appropriate locks for similar situations, but this seems like synchronize is sufficient.
synchronized private void parseCredentials() {...}
synchronized public UserCredentials getCredentials() { ... }
By declaring those methods synchronized only one thread at a time will be able to enter the method, essentially a barrier. That means that parseCredentials could have to wait for getCredentials, but getCredentials is so trivially fast you'll never notice.
That will synchronize on an instance of CredentialReader, so if you use more than one, you might want to synchronize on something else. As mentioned it the comments it is better to synchronize on a private object rather than the instance itself. It is a small change:
public class CredentialsReader {
private UserCredentials credentials;
private boolean isReading = false;
final private Object lock = new Object();
...
Then remove the synchronize from the method signature and add a synchronize call in the body.
private void parseCredentials() {
synchronize(lock){
//original code goes here.
}
}
Also, isReading should be volatile.
I do not suggest to do it manually, you could use a CountDownLatch with init value 1 provided in jdk.
You can let the readers calls await, and let the writer calls countDown once data is prepared.
So the reader could always get fully initialized data.

Access thread variable that changes from main thread

So, I am new to threads, and I'm still learning how everything works. So, I couldn't find an answer that would provide an explanation for my problem (to my level of understanding).
I have a Runnable class that looks like so:
public class Request implements Runnable {
private Boolean ok = true;
public synchronized void setOk(Boolean ok) {
this.ok = ok;
}
public synchronized Boolean getOk() {
return ok;
}
private synchronized void foo() {
//if something happens
setOk(false);
}
#Override
public void run() {
while (true)
foo();
}
}
And then I have another class that does the following:
private static Request request;
private static void spawnThreads() {
ExecutorService e = new Executors.newFixedThreadPool(4);
request = new Request();
e.execute(request);
}
public static void main(String[] args) {
spawnThreads();
while (true) {
System.out.println(request.getOk());
if (!request.getOk())
request.setOk(true);
TimeUnit.SECONDS.sleep(10);
}
}
I need that if in the main thread, that getOk() returns false, do something and set it to true. Viceversa, set it to false in the thread (which I need to keep on going, no matter what the value of ok is at any given time).
As this code is, I can't get the value of request.getOk() in the main thread. If I remove the synchronized words from the getter and setter, I can access the value in the main thread until a point in time when it is changed by the thread, and never again.
Also, the executor is used because I would create multiple Request objects, and waiting for it to shutdown before accessing the variable would contradict my reason for doing this, as I would need all the threads to keep running.
That thread is making http requests to a server (that randomly times out, denies response, etc) and is used to retrieve some information. The ok variable is there to take a note when the thread acquires an ok response and some information from the server.
How do I solve it so that the thread can update that variable, but the main thread to be able to retrieve it whenever needed, no matter if it was changed by the thread in the meanwhile or not.
Would changing my Runnable to a Callable help? If yes, how?
Your example still leaves some holes in the thread-safety. Like mentioned by #Radiodef using AtomicBoolean can relieve you of most of the synchronisation if used properly.
Using your example, this is a thread safe Request class that accepts a message, like an answer to a http request.
public final class Request implements Runnable {
private final AtomicBoolean ok = new AtomicBoolean(false);
// volatile variables promote reference changes through all threads
private volatile String msg;
private boolean setMessage(String responseMessage) {
if (this.ok.compareAndSet(false, true)) {
this.msg = msg;
return true;
}
return false;
}
public boolean hasMessage() {
// *pure* getters don't need synchronisation!
return this.ok.get();
}
public String getMessageAndReset() {
// make a copy before resetting the OK
String msgCopy = this.msg;
this.ok.compareAndSet(true, false);
return msgCopy;
}
public void run() {
final Random rand = new Random();
try {
while(true) {
// sleep at random max 5 seconds
// (simulate unpredictable network)
TimeUnit.SECONDS.sleep(rand.nextInt(5));
while(!setMessage("Incoming message")) {
// busy waiting ... waits until the current value has
// been retrieved by the main thread
Thread.sleep(100);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
}
And your main class:
public final class MainClazz implements Runnable {
private final ExecutorService exec;
private final Request request;
public void MainClazz() {
this.exec = new Executors.newFixedThreadPool(4);
this.request = new Request();
this.exec.execute(request);
}
public void run() {
while (true) {
if (request.hasMessage()) {
System.out.println(request.getMessageAndReset());
}
TimeUnit.SECONDS.sleep(10);
}
public static void main(String[] args) {
MainClazz main = new MainClazz();
main.run();
}
}
In this implementation, the Request class only holds a single value at a time. Depending the amount of data you expect you might want to think about using a buffer.
Also, like many others have mentioned, don't use while (true)! Get a synchronisation object from the java concurrent package!
More light reading on the AtomicBoolean object.

User Created Thread Pool Shutdown having different behaviour when a sysout is added

I was asked to create my own thread pool in an interview where I have to create the number of threads requested by the user. Allow user to submit there task and finally shutdown the pool. I wrote the below program which is working fine in all the cases other than shutdown.
public class ThreadPool
{
public final Queue<Runnable> workerQueue;
private static boolean isrunning = true;
private Thread[] workerThreads;
public ThreadPool(int N)
{
workerQueue = new LinkedList<>();
workerThreads = new Thread[N];
for (int i = 0; i < N; i++) {
workerThreads[i] = new Worker("Pool Thread " + i);
workerThreads[i].start();
}
}
public void shutdown()
{
while(isrunning){
if(workerQueue.isEmpty()){
isrunning = false;
}
}
}
public void submit(Runnable r) throws Exception
{
workerQueue.add(r);
}
private class Worker extends Thread
{
public Worker(String name)
{
super(name);
}
public void run()
{
while (isrunning) {
try {
if(!workerQueue.isEmpty())
{
Runnable r = workerQueue.poll();
r.run();
}
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
}
The Test method I wrote is like below
static public void main(String[] args) throws Exception
{
ClassA a1 = new ClassA();
ClassA a2 = new ClassA();
ClassA a3 = new ClassA();
ClassA a4 = new ClassA();
ClassA a5 = new ClassA();
ClassA a6 = new ClassA();
ThreadPool tp = new ThreadPool(5);
tp.submit(a1);
tp.submit(a2);
tp.submit(a3);
tp.submit(a4);
tp.submit(a5);
///////////////
tp.submit(a6);
tp.shutdown();
}
But the program is never ending, its running always and I have to stop it manually in eclipse. But if I add a simple System.out.print("") in my method shutdown, its working perfrectly(the Program is ended after the execution of all the threads).
Can you please tell me why its working with the sysout and why its not working with out it ?
You have two major problems with your code:
You are using an implementation of Queue that's not synchronized in a multithread environment. This leads to a Race Condition when multiple threads insert/remove from the queue. Please consider using something like:
workerQueue = new ConcurrentLinkedQueue()
You run some very tight loops, one in your Worker.run() method where you're not checking for NPE and not allowing for some "cooldown", and another one in shutdown():
while (isrunning) {
...
Runnable r = workerQueue.poll();
r.run();
...
}
This, coupled with 1, leads to the Queue being emptied without properly updating the size info: ie. isEmpty() returns false but poll() returns null. Your program will become stuck in a loop. This doesn't happen when you add System.out.print() due to different timing specific to your configuration (it can continue to fail in other environments - especially where there are more than 6 cpu cores available).

how can I insert data with thread in jdbc?

I want to insert data with using JDBC.
I write this code :
//I want to start threads here
while(stmt_ver.next()){
stmt_ver.setString(i, "test"+... );
stmt_ver.executeBatch();
connection_ver.commit();
}
//I want to finish threads here
How can I do this with thread?
Here you go. Updated answer with code
Threaded class
public class MyThreadedClass extends Thread{
//Do what I need here on a thread
public void run(){
//Do what I need here
}
}
Main
//Main class
public static class MyProgramMain{
//Program main
public static void main(String[] args) {
//Send 10 threads
for (int i=0; i<10; i++){
//Init class (threaded)
MyThreadedClass threadedClass = new MyThreadedClass();
//Execute code in the class run() method
threadedClass.start();
}
}
}
Your question is hard to answer. You are asking very vague. Try to be clear. Post all necessary code. Try to explain what you did and what you would like to do.
Here is some hint for you. It will not run if you copy and past it, but I think it should make clear what you can try:
int i = 0;
while(i < columnCount ){
// make a new statement
Statement stmt_ver = new Statement();
// set your data and make the statement ready
stmt_ver.set...
// make a new thread that executes your data
// and let it run
new Thread(){
public void run(){
stmt_ver.addBatch();
stmt_ver.executeBatch();
connection_ver.commit();
}
}.start();
i++;
}
This is a very simple solution. It will start a thread it each iteration. Since I/O typically is taking some time, this could improve the execution time of your code. But be aware - threading is not easy. This is a very simple, naive solution. It could cause more problems than it solves. If you are not familiar with threads (and it seems like you are not) don't do it!
new Thread(new Runnable(){
#Override public void run(){
//enter code here
}
}).start();
EDIT You want to insert with many threads in parallel ...
There are many different possibilities.
You should read about: Concurrency (concurrent collections) and Executors.
EDIT 2 I agree with Thomas Uhrig , that introducing Threads could be more a harm than a blessing here.
Why do you think it would be helpful?
public class MockCommonDao {
ArrayList<ArrayList> listOlists = new ArrayList<ArrayList>();
public List CommonInsert(List<Object> example)
{
List<Future<Object>> listOlists = null;
ExecutorService executor = Executors.newFixedThreadPool(example.size());
List<TransactionImpl> callingList = new ArrayList<MockCommonDao.TransactionImpl>();
for (int i = 0; i < example.size(); i++) {
TransactionImpl localImpl = new TransactionImpl(example.get(i));
callingList.add(localImpl);
}
try {
listOlists = executor.invokeAll(callingList);
} catch (InterruptedException e) {
}
return listOlists;
}
private class TransactionImpl implements Callable<Object>{
private Object example;
TransactionImpl(Object Criteria) {
this.example = Criteria;
}
#Override
public Object call() throws Exception {
private class TransactionImpl implements Callable<Object>{
private Object example;
TransactionImpl(Object Criteria) {
this.example = Criteria;
}
#Override
public Object call() throws Exception {
while(stmt_ver.next()){
stmt_ver.setString(i, "test"+... );
stmt_ver.executeBatch();
connection_ver.commit();
}
}
}}
}
This code will make simualtaneous insert depending on value of your threads you want to create for insert.example.size() determines number of insert operations you want to perform.Hope you mean this.

Returning a value from Runnable

The run method of Runnable has return type void and cannot return a value. I wonder however if there is any workaround of this.
I have a method like this:
public class Endpoint {
public method() {
Runnable runcls = new RunnableClass();
runcls.run()
}
}
The method run is like this:
public class RunnableClass implements Runnable {
public JaxbResponse response;
public void run() {
int id = inputProxy.input(chain);
response = outputProxy.input();
}
}
I want to have access to response variable in method. Is this possible?
Use Callable<V> instead of using Runnable interface.
Example:
public static void main(String args[]) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<Integer>> set = new HashSet<>();
for (String word : args) {
Callable<Integer> callable = new WordLengthCallable(word);
Future<Integer> future = pool.submit(callable);
set.add(future);
}
int sum = 0;
for (Future<Integer> future : set) {
sum += future.get();
}
System.out.printf("The sum of lengths is %s%n", sum);
System.exit(sum);
}
In this example, you will also need to implement the class WordLengthCallable, which implements the Callable interface.
public void check() {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> result = executor.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return 10;
}
});
try {
int returnValue = result.get();
} catch (Exception exception) {
//handle exception
}
}
Have a look at the Callable class. This is usually submited via an executor service
It can return a future object which is returned when the thread completes
Yes, there are workaround. Just use queue and put into it value which you want to return. And take this value from another thread.
public class RunnableClass implements Runnable{
private final BlockingQueue<jaxbResponse> queue;
public RunnableClass(BlockingQueue<jaxbResponse> queue) {
this.queue = queue;
}
public void run() {
int id;
id =inputProxy.input(chain);
queue.put(outputProxy.input());
}
}
public class Endpoint{
public method_(){
BlockingQueue<jaxbResponse> queue = new LinkedBlockingQueue<>();
RunnableClass runcls = new RunnableClass(queue);
runcls.run()
jaxbResponse response = queue.take(); // waits until takes value from queue
}
}
If you add a field to RunnableClass you can set it in run and read it in method_. However, Runnable is a poor (the Java keyword) interface as it tells you nothing about the (the concept) interface (only useful line of the API docs: "The general contract of the method run is that it may take any action whatsoever."). Much better to use a more meaningful interface (that may return something).
One way is, we have to use Future - Callable approach.
Another way is, Instead of returning value, you can hold in object
Example:
class MainThread {
public void startMyThread() {
Object requiredObject = new Object(); //Map/List/OwnClass
Thread myThread = new Thread(new RunnableObject(requiredObject)).start();
myThread.join();
System.out.println(requiredObject.getRequiredValue());
}
}
class RunnableObject implements Runnable {
private Object requiredObject;
public RunnableObject(Object requiredObject) {
this.requiredObject = requiredObject;
}
public void run() {
requiredObject.setRequiredValue(xxxxx);
}
}
Because object scope is in the same scope so that you can pass object to thread and can retrieve in the main scope. But, most important thing is, we have to use join() method. Because main scope should be waiting for thread completion of its task.
For multiple thread case, you can use List/Map to hold the values from threads.
Try the following
public abstract class ReturnRunnable<T> implements Runnable {
public abstract T runForResult();
#Override
public void run() {
runForResult();
}
}
Take a look at the callable interface, perhaps this suites your needs. You can also try to get the value of the response field by calling a setter-method inside of your run() method
public void run() {
int id;
id =inputProxy.input(chain);
response = outputProxy.input();
OuterClass.setResponseData(response);
}

Categories

Resources