Alright, this is probably something simple, but I just can't get it.
package foo.foo.foo;
public class Vars {
public static boolean foo = false;
}
Alright, so that's my Vars class.
I then have a JFrame, with a JMenuBar,JMenu,and a JMenuItems.
items = new JCheckBoxMenuItem("Foo");
items.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
AbstractButton ab = (AbstractButton)e.getSource();
Vars.foo = ab.getModel().isSelected();
System.out.println(Vars.foo);
}
});
menu.add(items, 0);
menuBar.add(menu,0);
All is good, it returns true for the println.
Now, this is the actual problem part...
I have a if statement
if(Vars.foo)
This -should- work, right? It never executes the code inside the if brackets, UNLESS I add this line of code above it.
System.out.println(Vars.foo);
That naturally prints true, then the if statement works, but if I comment out that line, it doesn't work.
I've also been googling, and tried this:
Vars v = null;
if(v.yoo)
That still won't do it unless I have the println, I have no idea why the println makes it work. Can you explain why/how this works?
Edit:
public class painthandling implements Runnable {
#Override
public void run() {
Vars y = null;
while(true){
if(y.foo){
//some code here
}
System.out.println(y.foo);
}
}
}
That's the part that's not working, the if statement. always returns false.
frame f = new frame();
(new Thread(new painthandling())).start();
System.out.print("Got it.");
The JFrame part is called in the new frame, then the other class is called there, with the Vars class called in both. in painthandling(), the if statement returns false if it doesn't have the println.
Short answer: Make the variable volatile
Long answer:
I have done some testing, and I can actually reproduce your situation (at least I think it's the same). Consider this code:
public class Test {
public static boolean foo = false;
public static void main(String[] args) {
new Thread(new Runnable(){
#Override
public void run() {
while(true) {
try {
Thread.sleep(2000);
System.out.println("Swapping");
Test.foo = !Test.foo;
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}).start();
while(true) {
if(Test.foo) {
System.out.println("I'm here");
}
}
}
}
This never prints I'm here. However, as the OP states, adding a System.out.println to the while loop does make it print it. But interestingly enough, it can be any println statement. It doesn't need to print the variable value. So this works:
public class Test {
public static boolean foo = false;
public static void main(String[] args) {
new Thread(new Runnable(){
#Override
public void run() {
while(true) {
try {
Thread.sleep(2000);
System.out.println("Swapping");
Test.foo = !Test.foo;
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}).start();
while(true) {
if(Test.foo) {
System.out.println("I'm here");
}
System.out.println(""); // Doesn't have to be System.out.println(Test.foo);
// This also works (lock is just an object)
// synchronized(lock) {
// int a = 2;
// }
}
}
}
There are some other cases that also produces the "expected" output, and that is making the variable volatile, or doing a Thread.sleep() inside the while loop where the test is done. The reason it works when the System.out.println is probably because println is synchronized. And in fact, doing any synchronized operation inside the loop have the same effect. So to conclude, it's a threading (memory model) issue, and it can be resolved by marking the variable as volatile. But this does not change the fact that doing multithreaded access with a static variable is a bad idea.
I suggest reading Chapter 17 of the Java Language Specification to learn more about threads, synchronization and the Java memory model.
I didn't really read your post but after skimming it looks like you are trying to use the static method like this.
someMethod() {
Var var = null;
boolean bool = var.foo
}
The nice thing about static method and fields is that you don't have to instantiate them, try this instead:
someMethod() {
boolean bool = Var.foo
}
Related
Okay so I have tested this code on java 8, 11, and 14, they all have the same result.
This is bad practice and an unrealistic scenario, but I would like to understand the JVM internals that causes this to happen.
If you run this code you will notice that everything except the print part itself of system.out.println inside if execute.
At some point with a slightly different java version I managed to get it to print by changing "play" too volatile, but even that doesn't work now.
Please at least test the code before claiming it is simply deadlocking the variables or using the cache, it is not, the if executes and everything inside it works except the print part itself.
public class Main {
public static void main(String[] args) {
TestClass t = new TestClass();
System.out.println("Starting test");
new MyRunnable(t).start();
while (true)
t.testUpdate(System.currentTimeMillis());
}
}
public class MyRunnable extends Thread {
private TestClass t;
public MyRunnable(TestClass t) {
this.t = t;
}
#Override
public void run() {
try {
Thread.sleep(500L);
t.setPlay(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestClass {
private boolean play = false;
private long lastUpdate = 0;
private long updateRate = 2000;
private boolean hasSysoBeenHit = false;
public void testUpdate(long callTime) {
System.out.println(play);
System.out.println((callTime-lastUpdate));
if (this.play && ((callTime-lastUpdate) >= updateRate)) {
System.out.println("Updating! " + (hasSysoBeenHit = true));
this.lastUpdate = callTime;
}
System.out.println("hasbeenhit? " + hasSysoBeenHit);
}
public void setPlay(boolean t) {
System.out.println("Starting game...");
this.play = t;
}
}
Your code is suffering from a data race on the TestClass.play field: there are 2 threads accessing this field and at least one of them does a write. This is already indicated by #aerus.
If you make the field volatile, the data race gets removed. Look for the volatile variable rule in the Java Memory model.
I would also move the logic for the play checking to the begin of the testUpdate method:
public void testUpdate(long callTime) {
if(!play)return;
...
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.
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.
I'm using RxVertx which is a sort of RxJava along with Java8 and I have a compilation error.
Here is my code:
public rx.Observable<Game> findGame(long templateId, GameModelType game_model, GameStateType state) {
return context.findGame(templateId, state)
.flatMap(new Func1<RxMessage<byte[]>, rx.Observable<Game>>() {
#Override
public Observable<Game> call(RxMessage<byte[]> gameRawReply) {
Game game = null;
switch(game_model) {
case SINGLE: {
ebs.subscribe(new Action1<RxMessage<byte[]>>() {
#Override
public void call(RxMessage<byte[]> t1) {
if(!singleGame.contains(0) {
game = new Game(); // ERROR is at this line
singleGames.put(0, game);
} else {
game = singleGames.get(0); // ERROR is at this line
}
}
});
}
}
return rx.Observable.from(game);
}
});
}
The compilation error is:
"Local variable game defined in an enclosing scope must be final or effectively final"
I cannot define 'game' as final since I do allocation\set and return it at the end of the function.
How can I make this code compile??
Thanks.
I have a Holder class that I use for situations like this.
/**
* Make a final one of these to hold non-final things in.
*
* #param <T>
*/
public class Holder<T> {
private T held = null;
public Holder() {
}
public Holder(T it) {
held = it;
}
public void hold(T it) {
held = it;
}
public T held() {
return held;
}
public boolean isEmpty() {
return held == null;
}
#Override
public String toString() {
return String.valueOf(held);
}
}
You can then do stuff like:
final Holder<Game> theGame = new Holder<>();
...
theGame.hold(myGame);
...
{
// Access the game through the `final Holder`
theGame.held() ....
Since you need to not modify the reference of the object you can wrap the Game in something else.
The quickest (but ugly) fix is to use an array of size 1, then set the content of the array later. This works because the the array is effectively final, what is contained in the array doesn't have to be.
#Override
public Observable<Game> call(RxMessage<byte[]> gameRawReply) {
Game[] game = new Game[1];
switch(game_model) {
case SINGLE: {
ebs.subscribe(new Action1<RxMessage<byte[]>>() {
#Override
public void call(RxMessage<byte[]> t1) {
if(!singleGame.contains(0) {
game[0] = new Game();
singleGames.put(0, game[0]);
} else {
game[0] = singleGames.get(0);
}
}
});
}
}
return rx.Observable.from(game[0]);
}
Another similar option is to make a new class that has a Game field and you then set that field later.
Cyclops has Mutable, and LazyImmutable objects for handling this use case. Mutable is fully mutable, and LazyImmutable is set once.
Mutable<Game> game = Mutable.of(null);
public void call(RxMessage<byte[]> t1) {
if(!singleGame.contains(0) {
game.mutate(g -> new Game());
singleGames.put(0, game.get());
} else {
game[0] = game.mutate(g->singleGames.get(0));
}
}
LazyImmutable can be used to set a value, lazily, once :
LazyImmutable<Game> game = LazyImmutable.def();
public void call(RxMessage<byte[]> t1) {
//new Game() is only ever called once
Game g = game.computeIfAbsent(()->new Game());
}
You cant. At least not directly. U can use a wrapper class however: just define a class "GameContainer" with game as its property and foward a final reference to this container instead.
#dkatzel's suggestion is a good one, but there's another option: extract everything about retrieving/creating the Game into a helper method, and then declare final Game game = getOrCreateGame();. I think that's cleaner than the final array approach, though the final array approach will certainly work.
Although the other approaches look acceptable, I'd like to mention that you can't be sure subscribing to ebs will be synchronous and you may end up always returning null from the inner function. Since you depend on another Observable, you could just simply compose it through:
public rx.Observable<Game> findGame(
long templateId,
GameModelType game_model,
GameStateType state) {
return context.findGame(templateId, state)
.flatMap(gameRawReply -> {
switch(game_model) {
case SINGLE: {
return ebs.map(t1 -> {
Game game;
if (!singleGame.contains(0) {
game = new Game();
singleGames.put(0, game);
} else {
game = singleGames.get(0);
}
return game;
});
}
}
return rx.Observable.just(null);
});
}
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.