my problem is that:
search_text.addModifyListener(new ModifyListener() {
#Override
public void modifyText(ModifyEvent e) {
ArrayList<Object> GPDMvalue = (ArrayList<Object>) multiSortList.getValue();
ArrayList<Map<String, Object>> valueList = getDefaultValue(GPDMvalue);
multiSortList.clear();
if(getGPDMList().size()==0)return;
multiSortList.setDataSource(getGPDMList());//new thread 1
multiSortList.setDefaultOrAddValue(valueList);//new thread 2
}
});
when the text changing too fast ,and the thread 1 or thread 2 does't excute completely,and the maybe some problem,so i want add the synchronized like this
public synchronized void modifyText(ModifyEvent e),
is this still a override method and will it work?
"Whether or not a method is synchronized is an implementation detail of the method. Synchronization isn't specified anywhere as a declarative contract - it's not like you can synchronize in interfaces, either.
How a class implements whatever thread safety guarantees it provides is up to it."
Taken from here
Adding the synchronized keyword does not get in the way of overriding a method (it is still overridden) because the method's signature remains the same.
For more details see JLS-ยง9.4.1.3
You can override a synchronized method and you can also remove synchronized keyword.
abstract class SynchronizedClass {
public synchronized String myIterfaceMethod(String str){
return str;
}
}
public class OverrideSynchronozied extends SynchronizedClass{
#Override
public String myIterfaceMethod(String str){
return str;
}
public static void main(String[] args) {
SynchronizedClass ss = new OverrideSynchronozied();
System.out.println(ss.myIterfaceMethod("Class Instance"));
}
}
Related
This question already has answers here:
How to synchronize a static variable among threads running different instances of a class in Java?
(5 answers)
Closed 3 years ago.
Im new to multithreading and it's a bit confusing. How could I use the synchronize key to give an output of : 1 a then 2 b ? In other words, I want the first thread to access the static variable x, increment it and then the second thread to start.
public class Test1 extends Thread{
static int x=0;
String name;
Test1(String n){ name=n;}
public void increment() {
x=x+1;
System.out.println(x+" "+ name);
}
public void run() {
this.increment();
}
}
public class Main {
public static void main(String args[]) {
Test1 a= new Test1("a");
Test1 b= new Test1("b");
a.start();
b.start();
}
}
You can use synchronized static method (in the increment anyway you are just operating on the static field so why not to make it static?).
public static synchronized void increment() {
x=x+1;
System.out.println(x+" "+ name);
}
Such method is synchronizing on the whole class object.
If you really don't want for some reason to make this method static you can explicitely synchronize the critical section on the class object
public void increment() {
synchronized(Test1.class) {
x=x+1;
System.out.println(x+" "+ name);
}
}
I'd suggest using an AtomicInteger with a call to incrementAndGet(). This will atomically increment the variable as well as prevent other threads from returning calls to the variable until preceding locks are removed, so your increment method would be:
System.out.println(x.incrementAndGet()+" "+ name);
You can also use a synchronised block as other users have posted, but the drawback of both of the suggestions is that you are sacrificing control of a lock object, since the synchronised keyword on a method is equivalent to:
synchronized (this) { }
And referring to a class object does not keep the object internal to the class.
Question 1.
If we consider the following class:
public class Test {
public static LinkedList<String> list;
}
How would you make getting/setting thread-safe for the variable 'list'?
I guess I could do something like this:
public class Test {
private static LinkedList<String> list;
public static synchronized LinkedList<String> getList() {
return new LinkedList<>(list);
}
public static synchronized void setList(LinkedList<String> data) {
list = new LinkedList<>(data);
}
}
Question 2.
But how thread-safe is this? Would I have to initialize a new list each time to ensure other copies don't affect the variable?
Question 3.
If we consider this instead:
public class Test {
private static LinkedList<String> list;
public static synchronized void ManipulateList() {
// do stuff to 'list'
}
public static synchronized void ChangeList() {
// do more stuff to 'list'
}
}
where both methods 'ManipulateList' and 'ChangeList' might add or remove variables to the same list
Is this thread-safe? Does this mean that if thread 1 is accessing 'ManipulateList' then thread 2 is not able to access 'ChangeList' until thread 1 finishes accessing 'ManipulateList'?
I'm just not sure if I'm understanding the effects correctly.
Question 1.
public static LinkedList<String> list;
How would you make getting/setting thread-safe for the variable
'list'?
Avoid global [mutable] state. Just get rid of it.
Question 2.
public class Test {
private static LinkedList<String> list;
public static synchronized LinkedList<String> getList() {
return new LinkedList<>(list);
}
public static synchronized void setList(LinkedList<String> data) {
list = new LinkedList<>(data);
}
}
But how thread-safe is this? Would I have to initialize a new list
each time to ensure other copies don't affect the variable?
(I am going to assume by this you mean Test.list not the passed in data which, due to the defects of the Java collection library, is mutable itself.
So you are always accessing the list with the same lock held. You are always copying the list when dealing with the outside world. The members of the list are immutable, so you don't need any deep copying. All good.
The method have the lock held over an expensive operation not involving the variable, so we should do better here.
public static synchronized LinkedList<String> getList() {
// The `LinkedList` list points to is never mutated after set.
LinkedList<String> local;
synchronized (Test.class) {
local = list;
}
return new LinkedList<>(local);
}
public static void setList(LinkedList<String> data) {
LinkedList<String> local = new LinkedList<>(data);
synchronized (Test.class) {
list = local;
}
}
In theory, even without the change the lock needn't be held continuously for the entire copy. As it is a public lock object (but naughty, but common) data could wait on it releasing the lock temporarily. Obviously not significant here, but in real world cases it may lead to strangeness.
Slightly more obscurely, list could be made volatile and the lock elided.
Question 3.
private static LinkedList<String> list;
public static synchronized void ManipulateList() {
// do stuff to 'list'
}
public static synchronized void ChangeList() {
// do more stuff to 'list'
}
Is this thread-safe? Does this mean that if thread 1 is accessing
'ManipulateList' then thread 2 is not able to access 'ChangeList'
until thread 1 finishes accessing 'ManipulateList'?
Yes. Other than there may be waits and one of the methods could call the other, perhaps indirectly.
General notes.
Remove global [mutable] state.
Try to avoid shared mutable object (keep shared object immutable and mutable objects unshared).
Reduce the amount of code and time that locks are held for.
Copy mutable inputs and outputs.
I guess I could do something like this:
This isn't thread safe.
Specifically, the setter:
public static synchronized void setList(LinkedList<String> data) {
list = new LinkedList<>(data);
}
does not enforce that data is accessed exclusively for the duration of the setList method. As such, other threads could modify the list during the implicit iteration.
The code in question 3 is fine with respect to updates to the list, because the fact the methods are synchronized means that the list is accessed mutually exclusively, and the effects of one method invocation are visible to subsequent invocations.
But it's not entirely safe, because nefarious code can acquire (and hold onto) the monitor of Test, which could lead to a deadlock.
You can fix this specific issue by having an explicit monitor that can only be acquired inside the class:
class Test {
private final Object obj = new Object();
public static void ManipulateList() {
synchronized (obj) { ... }
}
public static void ChangeList() {
synchronized (obj) { ... }
}
}
Anything that subclasses your Test class could break your synchronization scheme because subclasses could directly access the list without the method-synchronization - either by subclassing your Test class or through reflection.
public class MyTestClass extends Test {
// blah...
public static changeTheList() {
this.list.add("Bypasses synchronization through direct access to the list.");
}
}
A better solution for synchronization is to initialize your list with a synchronized wrapper, like this:
public class Test {
private static LinkedList<String> list = Collections.synchronizedList(new LinkedList<>());
public static synchronized LinkedList<String> getList() {
return list;
}
public static synchronized void setList(LinkedList<String> newList) {
list = newList;
}
}
In the second snippet, you can now safely sub-class your Test class and access the list in a thread-safe manner because the list itself is synchronized.
You other option is to mark your Test class as final but you would still need to fix your implementation (you re-initialize the list in your getter's & setter's which is not a good idea).
Also -- I might suggest you look at some tutorials regarding synchronization -- a couple of suggestions:
https://www.baeldung.com/java-synchronized-collections
https://howtodoinjava.com/java/collections/arraylist/synchronize-arraylist/
This question already has answers here:
Synchronization on "this" or private Object in Java? [duplicate]
(4 answers)
Closed 4 years ago.
I found 2 ways for synchronize method:
First:
public static Integer number = 0;
public synchronized static void myMethod(){
number++;
number--;
}
Second:
public static Integer number = 0;
private static final Object mySemaphoreLock = new Object();
public static void myMethod(){
synchronized (mySemaphoreLock){
number++;
number--;
}
}
Are these two methods the same? What is the difference between them?
In the second case lock object s available only for your class.
In the first method some other code can acquire lock accidentally or on purpose and make your code not working as expected.
For example if first case it is possible to do the following
public class MyBadClass {
public static void badStuff() { //Acquire lock on class object and do forever loop. Because of that you will not be able to call YourClass.myMethod() in your first option
synchronized (YourClass.class) {
while(true);
}
}
}
These two methods are using different objects to synchronize on (class instance vs class field).
Your first method:
public synchronized static void myMethod(){
number++;
number--;
}
can be expressed as
public static void myMethod(){
synchronized (YourClass.class) {
number++;
number--;
}
}
so you are using a different object to synchronize on (YourClass's class object vs class's static field (mySemaphoreLock)) than
public static void myMethod() {
synchronized (mySemaphoreLock) {
number++;
number--;
}
}
In your example there's no difference, but you cannot rule out someone else (think 3rd-party code) that would also want to synchronize on your class's object (for reasons unknown) - that would impact the behaviour of your code.
In general it would be some other code doing something like:
class SomeOtherClass {
public void someOtherMethod() {
// for some reason SomeOtherClass synchronizes on YourClass.class
synchronized (YourClass.class) {
/* long running operation */
}
}
}
so even if you invoke YourClass.myMethod() in parallel, one would need for to wait for the other to finish.
If you choose the implemenation with mySemaphoreLock, that wouldn't happen - this piece of code would execute concurrently (as they use different objects to synchronize on) - so no competition.
Let's say I have a synchronized method on some class:
abstract class Foo {
public synchronized void foo() { // synchronized!
// ...
};
}
and I overrode it without using the synchronized modifier:
class Bar extends Foo {
#Override
public void foo() { // NOT synchronized!
super.foo();
// ...
}
}
I have a couple of specific question regarding this scenario:
Will the overridden method be implicitly synchronized as well?
If not, will the super-call be synchronized?
If there is no super-call, will anything be synchronized?
Is there a way to force an overriding method to use synchronized (I noticed that abstract method definitions or method definitions inside an interface don't allow the synchronized keyword)?
public synchronized void foo() { // synchronized!
// ...
};
Is essentially the same as:
public void foo() {
synchronized (this) { // synchronized!
// ...
}
};
The latter is more explicit, so I would generally suggest using that form. Or better using a lock that is a private field instead of the "outer" object.
So: 1. No. 2. Yes. 3. No. 4. Mark the method final and call a protected method that may be overridden.
public final void foo() {
synchronized (this) {
fooImpl();
}
};
protected void fooImpl() {
// ...
}
As ever, you may well be better off with delegation rather than subclassing.
Failing to use synchronized when overriding a synchronized method has the potential for causing runtime bugs. As a safeguard, there is an Eclipse checker you can turn on to detect this condition.
The default is "ignore". "Warning" is also a valid choice.
which will produce this message:
What would be the behaviour of the following program where static synchronized method and instance synchronized method is trying to access static field of same class in different threads? Will any thread get blocked? Its very confusing.
class MyClass
{
public static int i = 5;
public synchronized void m1()
{
System.out.println(i); //uses static field i of MyClass
//T1 is executing this method
}
public static synchronized void m3()
{
//T2 will be able to call this method on same object lock while it is using
//static field i???
System.out.println(i);//uses static field i of MyClass
}
}
Synchronized instance methods are equivalent of
public void m1() {
synchronized(this) {
...
}
}
(well, they are not exactly the same, but the answer to your question does not suffer from that difference).
Synchronized static methods are synchronized on the class:
public void m2() {
synchronized(MyClass.class) {
...
}
}
As you can see, two block are synchronized on difference objects: m1 is synchronized on the instance it is called on, and m2 is synchronized on the instance of Class<MyClass> which represents your class in JVM. So those two methods can be called without blocking each other.
You are always synchronizing on an object.
Funciton m1 synchronizes on an instance of an object on which it is called.
Function m3 synchronizes on the class itself.
m1 could be written as:
public void m1()
{
synchronized(this) {
System.out.println(i); //uses static field i of MyClass
//T1 is executing this method
}
}
Therefore you are synchronizing on two different objects and these two methods can acces any global variable concurrently.
Your sample code looks good.
Best way to assure synchronization of static variables according to me is. As lock object is not accessible outside your Class. See below.
public class MyClass
{
private static int i = 0;
private static final Object lockObject = new Object();
public void m1() {
synchronized (lockObject ) {
//Use you static var
}
}
public void m3() {
synchronized (lockObject ) {
//Use you static var
}
}
}
The method m1 and m3 can be executed independently.
Because as you already said static synchronized is on the object. Therefore the same as synchronize(MyClass.class).
synchronized are instance wide usable. So it is only blocked for the instances. It would be the same as using:
MyClass myClass = new MyClass();
synchronize (myClass)
{
.....
}
Java does not have any synchronization controls that relate to accessing static fields.
If you make your methods empty, the synchronization will be exactly the same.
Specifically, as long as any thread is executing any synchronized static method in that type, all other threads that call synchronized static methods will wait for them to finish, so that at most one synchronized static method will be executing at once.