www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Synchronized classes have no public members

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
https://github.com/D-Programming-Language/dmd/pull/5188 implements a 
rule defined in TDPL: synchronized classes shall have no public members.

The motivation behind this limitation is that member accesses in 
synchronized objects should not occur without some handshake occurring. 
Public members would make that possible and easy.

Walter and I are on board with this change. However, it is a breaking 
change so we want to gather a level of community support before we push 
the button.


Thanks,

Andrei
Oct 12 2015
next sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, 13 October 2015 at 06:58:28 UTC, Andrei Alexandrescu 
wrote:
 https://github.com/D-Programming-Language/dmd/pull/5188 
 implements a rule defined in TDPL: synchronized classes shall 
 have no public members.

 The motivation behind this limitation is that member accesses 
 in synchronized objects should not occur without some handshake 
 occurring. Public members would make that possible and easy.

 Walter and I are on board with this change. However, it is a 
 breaking change so we want to gather a level of community 
 support before we push the button.
Well, as I understand it, technically, synchronized classes don't even exist in D at the moment - just synchronized functions (much as TDPL talks about D having synchronized classes and not synchronized functions). So, if that change only affects classes marked with synchronized and doesn't do anything to functions marked as synchronized, then the breakage is likely to be pretty small (pretty much just cases where someone didn't want to bother putting synchronized on every method individually). On the other hand, if it basically adds synchronized classes and disallows synchronized functions and actually moves us to what TDPL describes (or close to it), then it's basically going to break all uses of synchronized in classes aside from simply using synchronized blocks inside of a member function. If it's the latter, we definitely need an appropriate transition period. Ultimately, I think that we're better off with TDPL's definition of synchronized classes than the synchronized functions that we have now, so I do think that the change should be made. However, I also think that synchronized classes as TDPL describes are limited enough to be of questionable usefulness. Stripping off the outer layer of shared is unlikely to be sufficient in all but basic cases (and synchronized classes can't do any better than that, I don't think), meaning that you're likely going to have to cast away shared to do much with shared anyway, in which case, having a synchronized class loses at least some of its value. It can still encapsulate shared (which is good), but it doesn't necessarily make it much easier or safer to use. - Jonathan M Davis
Oct 13 2015
parent reply Benjamin Thaut <code benjamin-thaut.de> writes:
On Tuesday, 13 October 2015 at 07:17:20 UTC, Jonathan M Davis 
wrote:
 Ultimately, I think that we're better off with TDPL's 
 definition of synchronized classes than the synchronized 
 functions that we have now, so I do think that the change 
 should be made. However, I also think that synchronized classes 
 as TDPL describes are limited enough to be of questionable 
 usefulness. Stripping off the outer layer of shared is unlikely 
 to be sufficient in all but basic cases (and synchronized 
 classes can't do any better than that, I don't think), meaning 
 that you're likely going to have to cast away shared to do much 
 with shared anyway, in which case, having a synchronized class 
 loses at least some of its value. It can still encapsulate 
 shared (which is good), but it doesn't necessarily make it much 
 easier or safer to use.

 - Jonathan M Davis
I have to agree here. I think synchronized classes are of very little use, especially because they don't "cast away" shared in a useful way. It still has to be done manually. I think we should remove them. Synchronized methods should also be removed in my eyes. Making each and every object bigger by one pointer just for the sake of a few synchronized methods doesn't seem to be a good trade off to me. The entire synchronized methods give the user the feeling that he simply slaps synchronized on his class / method and then its thread safe and he doesn't have to care about threads anymore. In the real world this is far from true however. So synchronized methods and classes just give a false sense of thread safety and should rather be removed.
Oct 13 2015
next sibling parent reply Chris <wendlec tcd.ie> writes:
On Tuesday, 13 October 2015 at 08:55:26 UTC, Benjamin Thaut wrote:
 I have to agree here. I think synchronized classes are of very 
 little use, especially because they don't "cast away" shared in 
 a useful way. It still has to be done manually. I think we 
 should remove them. Synchronized methods should also be removed 
 in my eyes. Making each and every object bigger by one pointer 
 just for the sake of a few synchronized methods doesn't seem to 
 be a good trade off to me. The entire synchronized methods give 
 the user the feeling that he simply slaps synchronized on his 
 class / method and then its thread safe and he doesn't have to 
 care about threads anymore. In the real world this is far from 
 true however. So synchronized methods and classes just give a 
 false sense of thread safety and should rather be removed.
Actually, I once fell foul of this wrong impression of thread safety via 'synchronized'. I found a different solution and dropped synchronized.
Oct 13 2015
parent reply ponce <contact gam3sfrommars.fr> writes:
On Tuesday, 13 October 2015 at 09:07:54 UTC, Chris wrote:
 On Tuesday, 13 October 2015 at 08:55:26 UTC, Benjamin Thaut 
 wrote:
 I have to agree here. I think synchronized classes are of very 
 little use, especially because they don't "cast away" shared 
 in a useful way. It still has to be done manually. I think we 
 should remove them. Synchronized methods should also be 
 removed in my eyes. Making each and every object bigger by one 
 pointer just for the sake of a few synchronized methods 
 doesn't seem to be a good trade off to me. The entire 
 synchronized methods give the user the feeling that he simply 
 slaps synchronized on his class / method and then its thread 
 safe and he doesn't have to care about threads anymore. In the 
 real world this is far from true however. So synchronized 
 methods and classes just give a false sense of thread safety 
 and should rather be removed.
Actually, I once fell foul of this wrong impression of thread safety via 'synchronized'. I found a different solution and dropped synchronized.
I also dropped synchronized and use nogc mutexes instead. I also think synchronized methods should be removed. It's also difficult to explain: what is a "monitor"? when you write a synchronized { } block, which monitor is taken?
Oct 13 2015
next sibling parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Tue, 13 Oct 2015 09:36:22 +0000
schrieb ponce <contact gam3sfrommars.fr>:

 On Tuesday, 13 October 2015 at 09:07:54 UTC, Chris wrote:
 On Tuesday, 13 October 2015 at 08:55:26 UTC, Benjamin Thaut=20
 wrote:
 [=E2=80=A6] The entire synchronized methods give the user the feeling
 that he simply slaps synchronized on his class / method and
 then its thread safe and he doesn't have to care about threads
 anymore. In the real world this is far from true however. So
 synchronized methods and classes just give a false sense of
 thread safety and should rather be removed.
Actually, I once fell foul of this wrong impression of thread=20 safety via 'synchronized'. I found a different solution and=20 dropped synchronized.
=20 I also dropped synchronized and use nogc mutexes instead. I also=20 think synchronized methods should be removed. It's also difficult=20 to explain: what is a "monitor"? when you write a synchronized {=20 } block, which monitor is taken?
Yep, I prefer to think it sets of variables that need mutex protection. And these are not generally the set of member fields in a class. When other mutexes need the same variables they must be a strict superset or subset of the other with the mutex with smaller scope always being locked first. That's all folks. 100% safety. :) (The catch is you need to get a fix on the variables.) --=20 Marco
Oct 13 2015
parent reply ponce <contact gam3sfrommars.fr> writes:
On Tuesday, 13 October 2015 at 10:57:55 UTC, Marco Leise wrote:
 Yep, I prefer to think it sets of variables that need mutex 
 protection. And these are not generally the set of member 
 fields in a class.
Exactly. And that makes things using synchronized prone to longer and more frequent locks.
Oct 13 2015
parent Sean Kelly <sean invisibleduck.org> writes:
On Tuesday, 13 October 2015 at 11:51:02 UTC, ponce wrote:
 On Tuesday, 13 October 2015 at 10:57:55 UTC, Marco Leise wrote:
 Yep, I prefer to think it sets of variables that need mutex 
 protection. And these are not generally the set of member 
 fields in a class.
Exactly. And that makes things using synchronized prone to longer and more frequent locks.
Yep. Labeling methods and classes as synchronized and shared is mostly for the sake of facilitating static analysis. But I think it comes at the cost of good program design. Beyond facilitating a direct port of Java code I don't know why you'd use synchronized at the method or class level.
Oct 17 2015
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= writes:
On Tuesday, 13 October 2015 at 09:36:23 UTC, ponce wrote:
 It's also difficult to explain: what is a "monitor"?
Not difficult? A monitor is facade/object which only allows one method to execute concurrently. It can work out ok if synchronization/lockfree mechanisms are built into the language so that the compiler can optimize away overhead.
Oct 13 2015
prev sibling next sibling parent reply Minas Mina <minas_0 hotmail.co.uk> writes:
On Tuesday, 13 October 2015 at 08:55:26 UTC, Benjamin Thaut wrote:
 On Tuesday, 13 October 2015 at 07:17:20 UTC, Jonathan M Davis 
 wrote:
 Ultimately, I think that we're better off with TDPL's 
 definition of synchronized classes than the synchronized 
 functions that we have now, so I do think that the change 
 should be made. However, I also think that synchronized 
 classes as TDPL describes are limited enough to be of 
 questionable usefulness. Stripping off the outer layer of 
 shared is unlikely to be sufficient in all but basic cases 
 (and synchronized classes can't do any better than that, I 
 don't think), meaning that you're likely going to have to cast 
 away shared to do much with shared anyway, in which case, 
 having a synchronized class loses at least some of its value. 
 It can still encapsulate shared (which is good), but it 
 doesn't necessarily make it much easier or safer to use.

 - Jonathan M Davis
I have to agree here. I think synchronized classes are of very little use, especially because they don't "cast away" shared in a useful way. It still has to be done manually. I think we should remove them. Synchronized methods should also be removed in my eyes. Making each and every object bigger by one pointer just for the sake of a few synchronized methods doesn't seem to be a good trade off to me. The entire synchronized methods give the user the feeling that he simply slaps synchronized on his class / method and then its thread safe and he doesn't have to care about threads anymore. In the real world this is far from true however. So synchronized methods and classes just give a false sense of thread safety and should rather be removed.
I agree that synchronized classes / functions that not that useful. But synchronized statements, to me, make the intention of locking explicit. Maybe the internal monitor could be removed (with synchronized classes / functions as well), and allow synchronized() {} to be called on Lock objects, that essentially locks them at the beginning and unlocks them at the end.
Oct 13 2015
parent reply Benjamin Thaut <code benjamin-thaut.de> writes:
On Tuesday, 13 October 2015 at 12:20:17 UTC, Minas Mina wrote:
 I agree that synchronized classes / functions that not that 
 useful.

 But synchronized statements, to me, make the intention of 
 locking explicit.
Synchronized statements are fine and serve a good purpose, no need to delete them in my opinion.
 Maybe the internal monitor could be removed (with synchronized 
 classes / functions as well), and allow synchronized() {} to be 
 called on Lock objects, that essentially locks them at the 
 beginning and unlocks them at the end.
Yes, I would love that.
Oct 13 2015
parent reply Dicebot <public dicebot.lv> writes:
On Tuesday, 13 October 2015 at 12:51:14 UTC, Benjamin Thaut wrote:
 On Tuesday, 13 October 2015 at 12:20:17 UTC, Minas Mina wrote:
 I agree that synchronized classes / functions that not that 
 useful.

 But synchronized statements, to me, make the intention of 
 locking explicit.
Synchronized statements are fine and serve a good purpose, no need to delete them in my opinion.
 Maybe the internal monitor could be removed (with synchronized 
 classes / functions as well), and allow synchronized() {} to 
 be called on Lock objects, that essentially locks them at the 
 beginning and unlocks them at the end.
Yes, I would love that.
Isn't dedicated language feature a bit too much for a glorified mutex scope guard?
Oct 13 2015
parent reply Marco Leise <Marco.Leise gmx.de> writes:
Am Tue, 13 Oct 2015 12:52:55 +0000
schrieb Dicebot <public dicebot.lv>:

 On Tuesday, 13 October 2015 at 12:51:14 UTC, Benjamin Thaut wrote:
 On Tuesday, 13 October 2015 at 12:20:17 UTC, Minas Mina wrote:
 I agree that synchronized classes / functions that not that 
 useful.

 But synchronized statements, to me, make the intention of 
 locking explicit.
Synchronized statements are fine and serve a good purpose, no need to delete them in my opinion.
 Maybe the internal monitor could be removed (with synchronized 
 classes / functions as well), and allow synchronized() {} to 
 be called on Lock objects, that essentially locks them at the 
 beginning and unlocks them at the end.
Yes, I would love that.
Isn't dedicated language feature a bit too much for a glorified mutex scope guard?
Guys, sorry to break into your wishful thinking, but synchronized(mutex) {} already works as you want it to since as long as I can think. Yes, it takes a parameter, yes it calls lock/unlock on the mutex. :) -- Marco
Oct 13 2015
next sibling parent reply Dicebot <public dicebot.lv> writes:
On Tuesday, 13 October 2015 at 18:28:23 UTC, Marco Leise wrote:
 Guys, sorry to break into your wishful thinking, but

    synchronized(mutex) {}

 already works as you want it to since as long as I can think. 
 Yes, it takes a parameter, yes it calls lock/unlock on the 
 mutex. :)
Yes, and I am saying that it doesn't justify presence of `synchronized` keyword in the language at all, being historical legacy misfeature.
Oct 13 2015
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, 13 October 2015 at 19:05:31 UTC, Dicebot wrote:
 On Tuesday, 13 October 2015 at 18:28:23 UTC, Marco Leise wrote:
 Guys, sorry to break into your wishful thinking, but

    synchronized(mutex) {}

 already works as you want it to since as long as I can think. 
 Yes, it takes a parameter, yes it calls lock/unlock on the 
 mutex. :)
Yes, and I am saying that it doesn't justify presence of `synchronized` keyword in the language at all, being historical legacy misfeature.
The same can be done trivially with a guard/autolock object, because we have RAII. It can also be done with scope statements, though that's more verbose. I suspect that C# has it primarily because they don't have RAII. I don't know that it really hurts D to have synchronized statements, but I do agree that they really don't add much in the way of value. And it's not like it's hard to come up with cases where they don't even work, whereas a guard/autolock could (e.g. having to unlock the mutex partway through a block, possibly relocking it later in the block, possibly not). - Jonathan M Davis
Oct 13 2015
prev sibling next sibling parent reply flamencofantasy <flamencofantasy gmail.com> writes:
On Tuesday, 13 October 2015 at 19:05:31 UTC, Dicebot wrote:
 On Tuesday, 13 October 2015 at 18:28:23 UTC, Marco Leise wrote:
 Guys, sorry to break into your wishful thinking, but

    synchronized(mutex) {}

 already works as you want it to since as long as I can think. 
 Yes, it takes a parameter, yes it calls lock/unlock on the 
 mutex. :)
Yes, and I am saying that it doesn't justify presence of `synchronized` keyword in the language at all, being historical legacy misfeature.
+1 Please remove synchronized all together. It's an abomination which should have never been in D in the first place. It encourages sloppiness and lobotomizes programmers! The greatest good you can do to all the D code out there that makes use of synchronized is to kill synchronized. Then they'll have to think and hopefully learn how to properly synchronize sections of code instead of locking everything everywhere all the time.
Oct 13 2015
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/14/15 6:33 AM, flamencofantasy wrote:
 On Tuesday, 13 October 2015 at 19:05:31 UTC, Dicebot wrote:
 On Tuesday, 13 October 2015 at 18:28:23 UTC, Marco Leise wrote:
 Guys, sorry to break into your wishful thinking, but

    synchronized(mutex) {}

 already works as you want it to since as long as I can think. Yes, it
 takes a parameter, yes it calls lock/unlock on the mutex. :)
Yes, and I am saying that it doesn't justify presence of `synchronized` keyword in the language at all, being historical legacy misfeature.
+1 Please remove synchronized all together. It's an abomination which should have never been in D in the first place. It encourages sloppiness and lobotomizes programmers! The greatest good you can do to all the D code out there that makes use of synchronized is to kill synchronized. Then they'll have to think and hopefully learn how to properly synchronize sections of code instead of locking everything everywhere all the time.
Scoped locking as embodied by "synchronized" has many meaningful uses. Facebook uses https://github.com/facebook/folly/blob/master/folly/docs/Synchronized.md often and with great results. C++1x has made it a language rule that the entire STL implements mutable and const methods as expected by folly::Synchronized. -- Andrei
Oct 15 2015
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/13/15 10:05 PM, Dicebot wrote:
 On Tuesday, 13 October 2015 at 18:28:23 UTC, Marco Leise wrote:
 Guys, sorry to break into your wishful thinking, but

    synchronized(mutex) {}

 already works as you want it to since as long as I can think. Yes, it
 takes a parameter, yes it calls lock/unlock on the mutex. :)
Yes, and I am saying that it doesn't justify presence of `synchronized` keyword in the language at all, being historical legacy misfeature.
For a while we were of the opinion that we should let "synchronized" and "shared" be and move on with alternative features. Now we believe an incomplete language definition is damaging the language as a whole so we better make them fully defined and useful within their charter. Lock-based synchronization has plenty of good uses and the scope locking defined by "synchronized" covers a large useful subset of it. We need to make it usable safely and without contortions, and this particular PR is a step along that way. It's not a huge priority but since Andrej has only done the work, the main concern left is breakage of existing code, albeit much of that is incorrect or unnecessarily unsafe. Andrei
Oct 15 2015
next sibling parent Paolo Invernizzi <paolo.invernizzi no.address> writes:
On Thursday, 15 October 2015 at 10:11:06 UTC, Andrei Alexandrescu 
wrote:
 Now we believe an incomplete language definition is damaging 
 the language as a whole so we better make them fully defined 
 and useful within their charter.
+1! --- Paolo
Oct 15 2015
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 15 October 2015 at 10:11:06 UTC, Andrei Alexandrescu 
wrote:
 On 10/13/15 10:05 PM, Dicebot wrote:
 On Tuesday, 13 October 2015 at 18:28:23 UTC, Marco Leise wrote:
 Guys, sorry to break into your wishful thinking, but

    synchronized(mutex) {}

 already works as you want it to since as long as I can think. 
 Yes, it
 takes a parameter, yes it calls lock/unlock on the mutex. :)
Yes, and I am saying that it doesn't justify presence of `synchronized` keyword in the language at all, being historical legacy misfeature.
For a while we were of the opinion that we should let "synchronized" and "shared" be and move on with alternative features. Now we believe an incomplete language definition is damaging the language as a whole so we better make them fully defined and useful within their charter. Lock-based synchronization has plenty of good uses and the scope locking defined by "synchronized" covers a large useful subset of it. We need to make it usable safely and without contortions, and this particular PR is a step along that way. It's not a huge priority but since Andrej has only done the work, the main concern left is breakage of existing code, albeit much of that is incorrect or unnecessarily unsafe.
Unless we're going to decide to get rid of synchronized in favor of just using mutexes and guards/autolocks like you would in C++, I think that it's pretty clear that this change is an improvement. And it's what TDPL has said for something like 5 years now. So, in theory, it's publicly been the plan for some time. - Jonathan M Davis
Oct 15 2015
prev sibling next sibling parent Dicebot <public dicebot.lv> writes:
On Thursday, 15 October 2015 at 10:11:06 UTC, Andrei Alexandrescu 
wrote:
 Yes, and I am saying that it doesn't justify presence of 
 `synchronized`
 keyword in the language at all, being historical legacy 
 misfeature.
For a while we were of the opinion that we should let "synchronized" and "shared" be and move on with alternative features. Now we believe an incomplete language definition is damaging the language as a whole so we better make them fully defined and useful within their charter. Lock-based synchronization has plenty of good uses and the scope locking defined by "synchronized" covers a large useful subset of it. We need to make it usable safely and without contortions, and this particular PR is a step along that way. It's not a huge priority but since Andrej has only done the work, the main concern left is breakage of existing code, albeit much of that is incorrect or unnecessarily unsafe.
You are absolutely correct that incomplete definition is damaging. I can also agree with "plenty of uses" but hardly with "plenty of good uses" though. There are many situations of course where efficient concurrency is not critical and one can go away with straightforward mutex approach. But providing such semantics as language builtin implies it is encouraged and "official" approach and that is rather bad :( To be honest I'd prefer it to go in "not really deprecated but pretend it doesn't exist" trash bin like scope storage class is.
 the main concern left is breakage of existing code, albeit much 
 of that is incorrect or unnecessarily unsafe.
This is a bit more delicate issue. This code is only incorrect and/or unsafe if used in multi-threaded environment and those fields are actually accessed. There isn't anything broken with such code per se. I agree it should be fixed (with a proper slow deprecation phase) but I am not happy about it.
Oct 15 2015
prev sibling parent deadalnix <deadalnix gmail.com> writes:
On Thursday, 15 October 2015 at 10:11:06 UTC, Andrei Alexandrescu 
wrote:
 For a while we were of the opinion that we should let 
 "synchronized" and "shared" be and move on with alternative 
 features. Now we believe an incomplete language definition is 
 damaging the language as a whole so we better make them fully 
 defined and useful within their charter.

 Lock-based synchronization has plenty of good uses and the 
 scope locking defined by "synchronized" covers a large useful 
 subset of it. We need to make it usable safely and without 
 contortions, and this particular PR is a step along that way.

 It's not a huge priority but since Andrej has only done the 
 work, the main concern left is breakage of existing code, 
 albeit much of that is incorrect or unnecessarily unsafe.
I'm on board with that. Half baked feature is really the worse. We should really make sure we either don't do something or do it well.
Oct 15 2015
prev sibling next sibling parent reply Kapps <opantm2+spam gmail.com> writes:
On Tuesday, 13 October 2015 at 18:28:23 UTC, Marco Leise wrote:
 Guys, sorry to break into your wishful thinking, but

    synchronized(mutex) {}

 already works as you want it to since as long as I can think. 
 Yes, it takes a parameter, yes it calls lock/unlock on the 
 mutex. :)
Though really, that could just be: with(mutex.lock()) { }
Oct 13 2015
parent Artur Skawina via Digitalmars-d <digitalmars-d puremagic.com> writes:
On 10/14/15 03:10, Kapps via Digitalmars-d wrote:
 On Tuesday, 13 October 2015 at 18:28:23 UTC, Marco Leise wrote:
 Guys, sorry to break into your wishful thinking, but

    synchronized(mutex) {}

 already works as you want it to since as long as I can think. Yes, it takes a
parameter, yes it calls lock/unlock on the mutex. :)
Though really, that could just be: with(mutex.lock()) { }
Yes, but be careful - this is a relatively recent language change (AFAIR it went in during the 'we-don't-need-no-changelog' phase, so this was only documented in a bugzilla entry) _and_ it used to be broken until /very/ recently - the object was destroyed before entering the block. IOW it was executed like: auto __tmp = mutex.lock(); __tmp.__dtor(); { ... } which could result in nasty bugs, because you might not have immediately noticed that you're operating on an already unlocked object. artur
Oct 14 2015
prev sibling parent reply Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 13-Oct-2015 21:28, Marco Leise wrote:
 Am Tue, 13 Oct 2015 12:52:55 +0000
[snip]
 Guys, sorry to break into your wishful thinking, but

     synchronized(mutex) {}

 already works as you want it to since as long as I can think.
 Yes, it takes a parameter, yes it calls lock/unlock on the
 mutex. :)
Now how hard would it be to support any object (mutex kind) with lock/unlock? Or do we even need it with scope(exit)? -- Dmitry Olshansky
Oct 15 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/15/15 4:06 AM, Dmitry Olshansky wrote:
 On 13-Oct-2015 21:28, Marco Leise wrote:
 Am Tue, 13 Oct 2015 12:52:55 +0000
[snip]
 Guys, sorry to break into your wishful thinking, but

     synchronized(mutex) {}

 already works as you want it to since as long as I can think.
 Yes, it takes a parameter, yes it calls lock/unlock on the
 mutex. :)
Now how hard would it be to support any object (mutex kind) with lock/unlock?
AFAIK, the way this works is that mutex makes itself its own monitor object. So any other mutex-like object can follow this pattern. Or did I misunderstand the question?
 Or do we even need it with scope(exit)?
I personally find the enforcement of the scope guard much better than having to manually add the lock inside the scope. It gives a clear delineation of where the lock MUST go (before the scope is entered). you can simulate synchronized(mutex) {} like: { auto _lock = scopeLock(mutex); } But this is not nearly as robust. One could add junk before the lock, and no complaints from the compiler. I don't really understand all the disdain for synchronized here... -Steve
Oct 15 2015
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 15 October 2015 at 15:16:59 UTC, Steven 
Schveighoffer wrote:
 I don't really understand all the disdain for synchronized 
 here...
Because it's usually either the wrong solution or just unnecessary. If you are going to have a single mutex for an entire object, then it's nice in the way that it's nice that invariants are nice. They're not at all necessary, because the same thing can be done manually via assertions inside of all of the public member functions, but it does make them less error-prone. However, it's frequently the case that having a mutex per class object is the wrong way to go. Usually, it's better to have tighter locks than that which target specific member variables rather than the class as a whole, and when you do want it at the class level, it's frequently better to have the user of the class do the locking, since in that case, there's a decent chance that the object is a member variable inside of another class/struct where it and another set of variables need to share a mutex, so having a mutex built into the object is redundant and causes unnecessary overhead. Having the mutex at the class level is simply too inflexible and arguably encourages bad coding practices. So, having synchronized on classes or functions is of questionable value and arguably harmful - though the fact that having it on classes would allow us to strip away the outer layer of shared on the class' members does add some value. Ultimately, the only advantages to synchronized classes IMHO are: 1. They makes porting Java code easier. 2. Similar to how invariant helps with assertions at the class level, they make it easier to use a mutex at the class level correctly (though IMHO, that's almost always the wrong design). 3. They give us a way to implicitly cast away shared on some level (though not necessarily enough to be worth it). So, they add _some_ value, but I'm not at all convinced that they're worth it. As for synchronized statements/blocks, they're simply syntactic sugar that add no real value that I can see, and they can do less then the equivalent with guards/autolocks. These two pieces of code are equivalent: synchronized(mutex) { } { Guard guard(mutex); } and the second one is far more flexible, since it allows for stuff like guard.unlock() or using the mutex with a condition variable. So, synchronized statements are a poor-man's guard/autolock and simply not worth having IMHO unless we find some way that it allows us to get the compiler to do stuff (like being able to implicitly remove shared on some level, though because you have arbitrary code within the synchronized block and aren't dealing with encapsulated shared variables like with synchronized classes, I don't see how we really can get the compiler to do much special with synchronized blocks). I don't know that it's worth it to remove synchronized from the language, but certainly, if we were starting from scratch, I'd be arguing against it. I think that it's a Java-ism that shouldn't have been ported to D. Java and C# had no choice, because they don't have proper RAII or scope statements, but we don't have that problem. - Jonathan M Davis
Oct 15 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/15/15 11:50 AM, Jonathan M Davis wrote:
 On Thursday, 15 October 2015 at 15:16:59 UTC, Steven Schveighoffer wrote:
 I don't really understand all the disdain for synchronized here...
Because it's usually either the wrong solution or just unnecessary. If you are going to have a single mutex for an entire object, then it's nice in the way that it's nice that invariants are nice. They're not at all necessary, because the same thing can be done manually via assertions inside of all of the public member functions, but it does make them less error-prone.
I'm speaking just about the synchronized(mutex) statement, not about synchronized classes or methods. I don't think I've ever used a synchronized class.
 As for synchronized statements/blocks, they're simply syntactic sugar
 that add no real value that I can see, and they can do less then the
 equivalent with guards/autolocks. These two pieces of code are equivalent:

 synchronized(mutex)
 {
 }

 {
      Guard guard(mutex);
 }

 and the second one is far more flexible, since it allows for stuff like
 guard.unlock() or using the mutex with a condition variable.
You can do both of these with synchronized statements, mutex.unlock works and you can use with a condition variable. As I said before, with the Guard lock, you have more room for error, and visually the lock is better identified with a synchronized statement.
 So,
 synchronized statements are a poor-man's guard/autolock and simply not
 worth having IMHO unless we find some way that it allows us to get the
 compiler to do stuff (like being able to implicitly remove shared on
 some level, though because you have arbitrary code within the
 synchronized block and aren't dealing with encapsulated shared variables
 like with synchronized classes, I don't see how we really can get the
 compiler to do much special with synchronized blocks).
We could do away with new, and require people to call malloc and constructors directly. The sugar is nice, and keeps your code from making dumb mistakes. I see synchronized blocks as a clear advantage over arbitrary locking just from a cleanliness point of view. -Steve
Oct 15 2015
parent Dicebot <public dicebot.lv> writes:
On Thursday, 15 October 2015 at 17:10:23 UTC, Steven 
Schveighoffer wrote:
 You can do both of these with synchronized statements, 
 mutex.unlock works and you can use with a condition variable.

 As I said before, with the Guard lock, you have more room for 
 error, and visually the lock is better identified with a 
 synchronized statement.
There is no argument it looks nicer but it is a dedicated language feature for a minor syntax sugar over a feature that is almost never used in modern idiomatic concurrent code. Explicit locking in application code is rather old school, same as the notion that blindly adding more threads to existing OOP program helps to improve performance. It isn't bad to have it but don't forget Andrei's words about constant sum of language complexity - we could have had something more useful in totally different domain instead of it.
Oct 15 2015
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, 13 October 2015 at 08:55:26 UTC, Benjamin Thaut wrote:
 I have to agree here. I think synchronized classes are of very 
 little use, especially because they don't "cast away" shared in 
 a useful way. It still has to be done manually. I think we 
 should remove them. Synchronized methods should also be removed 
 in my eyes. Making each and every object bigger by one pointer 
 just for the sake of a few synchronized methods doesn't seem to 
 be a good trade off to me. The entire synchronized methods give 
 the user the feeling that he simply slaps synchronized on his 
 class / method and then its thread safe and he doesn't have to 
 care about threads anymore. In the real world this is far from 
 true however. So synchronized methods and classes just give a 
 false sense of thread safety and should rather be removed.
I'm fine with having synchronized classes, and I'm fine with having synchronized classes removed from the language entirely. I think that synchronized functions provide almost no value over simply using mutexes, and they give the false impression that slapping synchronized on it solves the concurrency problem, whereas it's often far more complicated than that. In most cases, it's better to have mutexes be for a specific variable or group of variables, in which case, having a single mutex for the object just risks folks reusing that mutex when they should be creating multiple mutexes. Having a single mutex for a class is usually overly broad - regardless of whether all of the functions in a class are synchronized or only select ones are. And when you _do_ use a single mutex for an entire class, I've found that it's often the case that the mutex shouldn't be part of the class, because you need to lock it with some other piece of data at the same time (e.g. lock a linked list variable and another, related, variable via a lock external to them rather than having the linked list manage its own lock and then need another lock around both of those variables). synchronized on functions/classes is just not a good replacement for explicit mutexes, and it encourages bad practices IMHO. The primary advantage that I see to synchronized classes is that they can safely, implicitly strip off the outer layer of shared - and that's the only way that we've come up with thus far that we can safely, implicitly strip off shared at all. However, because it's only the outer layer, I'm not sure that it's worth it. And creating whole classes just to encapsulate shared seems like overkill to me, especially if you end up having to cast away shared inside the class anyway. But even then, I would think that a synchronized class makes more sense as a small wrapper around a group of variables that need to be protected by a single mutex than it does to slap synchronized on a class like LinkedList, and I expect that there are going to be plenty of programmers looking to just slap synchronized on a class and have it magically fix their shared problems for them (and then getting annoyed when they still have shared problems inside of the class, because only the outer layer of shared was stripped off). So, if we have synchronized on classes or functions, I think that we should have synchronized classes, not individually synchronized functions. But I'm not convinced that having either synchronized classes or functions is actually a good idea. So, if we were to decide to deprecate the synchronized attribute altogether, it wouldn't hurt my feelings any. It's a misfeature from Java IMHO. But at least synchronized classes are a valiant attempt to get some value out of it. - Jonathan M Davis
Oct 13 2015
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= writes:
On Tuesday, 13 October 2015 at 18:27:43 UTC, Jonathan M Davis 
wrote:
 they should be creating multiple mutexes. Having a single mutex 
 for a class is usually overly broad - regardless of whether all 
 of the functions in a class are synchronized or only select 
 ones are. And when you _do_ use a single mutex for an entire 
 class, I've found that it's often the case that the mutex
Monitor classes is a high level convenience feature that one has to put work into if it is to be good. It is however much less error prone than mutexes and semaphores. The point is that you create a robust encapsulated facade and only weaken the facade after static analysis has proven that locks are superfluous. Doing this manually is error prone. One can also add high level concurrency mechanisms like guarantees for obtaining a set of resources before obtaining the lock, e.g. the caller supplies a predicate like "user Eric and user Lisa is available" and is suspended until the predicate is satisfiable. But it needs more high level features than D has today.
Oct 13 2015
prev sibling next sibling parent Nemanja Boric <4burgos gmail.com> writes:
On Tuesday, 13 October 2015 at 06:58:28 UTC, Andrei Alexandrescu 
wrote:
 https://github.com/D-Programming-Language/dmd/pull/5188 
 implements a rule defined in TDPL: synchronized classes shall 
 have no public members.

 The motivation behind this limitation is that member accesses 
 in synchronized objects should not occur without some handshake 
 occurring. Public members would make that possible and easy.

 Walter and I are on board with this change. However, it is a 
 breaking change so we want to gather a level of community 
 support before we push the button.


 Thanks,

 Andrei
While we're talking about this, what about this: http://www.digitalmars.com/d/archives/digitalmars/D/Module_access_to_private_members_of_synchronized_classes_228775.html
 In the TDPL, on page 419:
 "Not so for synchronized classes, which obey the following 
 rules:
- Access to private members is restricted to methods of the class." I could rework commits from my experimental branch and submit a PR?
Oct 13 2015
prev sibling next sibling parent reply Dicebot <public dicebot.lv> writes:
On Tuesday, 13 October 2015 at 06:58:28 UTC, Andrei Alexandrescu 
wrote:
 https://github.com/D-Programming-Language/dmd/pull/5188 
 implements a rule defined in TDPL: synchronized classes shall 
 have no public members.

 The motivation behind this limitation is that member accesses 
 in synchronized objects should not occur without some handshake 
 occurring. Public members would make that possible and easy.

 Walter and I are on board with this change. However, it is a 
 breaking change so we want to gather a level of community 
 support before we push the button.


 Thanks,

 Andrei
I still have no idea why I would ever use `synchronized` (any automatic thread synchronization is harmful in my opinion) so change itself is irrelevant. But it may break quite some old Java-liked 3d party code for no benefit and that would be annoying.
Oct 13 2015
parent reply Jacob Carlborg <doob me.com> writes:
On 2015-10-13 14:56, Dicebot wrote:

 I still have no idea why I would ever use `synchronized` (any automatic
 thread synchronization is harmful in my opinion) so change itself is
 irrelevant. But it may break quite some old Java-liked 3d party code for
 no benefit and that would be annoying.
Like DWT :) -- /Jacob Carlborg
Oct 13 2015
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/14/15 9:24 AM, Jacob Carlborg wrote:
 On 2015-10-13 14:56, Dicebot wrote:

 I still have no idea why I would ever use `synchronized` (any automatic
 thread synchronization is harmful in my opinion) so change itself is
 irrelevant. But it may break quite some old Java-liked 3d party code for
 no benefit and that would be annoying.
Like DWT :)
That may be worrisome. Any information on how many are using DWT, and how badly it would break if we pulled the change? If we assess there's too much breakage, we can define a DIP and make the check opt-in via a flag -dipNN. Andrei
Oct 15 2015
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 15 October 2015 at 14:28:00 UTC, Andrei Alexandrescu 
wrote:
 On 10/14/15 9:24 AM, Jacob Carlborg wrote:
 On 2015-10-13 14:56, Dicebot wrote:

 I still have no idea why I would ever use `synchronized` (any 
 automatic
 thread synchronization is harmful in my opinion) so change 
 itself is
 irrelevant. But it may break quite some old Java-liked 3d 
 party code for
 no benefit and that would be annoying.
Like DWT :)
That may be worrisome. Any information on how many are using DWT, and how badly it would break if we pulled the change? If we assess there's too much breakage, we can define a DIP and make the check opt-in via a flag -dipNN.
The current behavior needs to be deprecated first regardless. We shouldn't just throw a switch and make it illegal to access member variables of a synchronized class. If we start with a deprecation message about it and only move to making it illegal later, then it really shouldn't matter much what existing code is doing. A switch makes sense if we intend to experiment with this rather than necessarily being the case that we want to go in this direction. But even then, we'd have to either deprecate the current behavior at some point or just break everyone's code who hadn't bothered to use the switch. But given the general hostility to synchronized in this thread (for whatever that's worth given the relatively few people involved), it could very well be that future discussions on shared/synchronized would lean towards just axing synchronized, making any changes we do to it now moot. Still, from a correctness standpoint, I think that it's pretty clear that synchronized classes are better than synchronized functions. - Jonathan M Davis
Oct 15 2015
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2015-10-15 16:28, Andrei Alexandrescu wrote:

 That may be worrisome. Any information on how many are using DWT, and
 how badly it would break if we pulled the change?
I have no idea how many are using DWT. At least a couple of developers, i.e. that I see in PR's and on the forum. grep returned 238 occurrences of "synchronized", this include both synchronized methods and the synchronized statement. Very few false positives (two that I know for sure). -- /Jacob Carlborg
Oct 15 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-10-15 16:28, Andrei Alexandrescu wrote:

 That may be worrisome. Any information on how many are using DWT, and
 how badly it would break if we pulled the change?

 If we assess there's too much breakage, we can define a DIP and make the
 check opt-in via a flag -dipNN.
I would like to add that the impact of a possible breakage depends on what the alternative is. If a function in Phobos or druntime is provided with the same functionality, then the breakage have less of an impact. If D supported trailing delegate syntax (hint, hint) then it would be possible to have a library implementation with the exact same syntax. Although I guess there would be a conflict with the keyword during the deprecation phase. -- /Jacob Carlborg
Oct 15 2015
parent reply Dicebot <public dicebot.lv> writes:
On Friday, 16 October 2015 at 06:26:30 UTC, Jacob Carlborg wrote:
 On 2015-10-15 16:28, Andrei Alexandrescu wrote:

 That may be worrisome. Any information on how many are using 
 DWT, and
 how badly it would break if we pulled the change?

 If we assess there's too much breakage, we can define a DIP 
 and make the
 check opt-in via a flag -dipNN.
I would like to add that the impact of a possible breakage depends on what the alternative is. If a function in Phobos or druntime is provided with the same functionality, then the breakage have less of an impact.
As far as I understand topic is about deprecating direct field access of synchronized classes, method calls in synhronized classes and `synchronized () {}` blocks will remain untouched.
Oct 15 2015
next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-10-16 08:49, Dicebot wrote:

 As far as I understand topic is about deprecating direct field access of
 synchronized classes, method calls in synhronized classes and
 `synchronized () {}` blocks will remain untouched.
Yeah, that was the original topic. Then I interpreted it like all uses of "synchronized" would be deprecated. Synchronized classes are not used in DWT. -- /Jacob Carlborg
Oct 16 2015
parent reply Dicebot <public dicebot.lv> writes:
On Friday, 16 October 2015 at 07:00:42 UTC, Jacob Carlborg wrote:
 Yeah, that was the original topic. Then I interpreted it like 
 all uses of "synchronized" would be deprecated.
That would be really bold thing to do, I don't think anyone realistically proposes that. At most I'd suggest to explicitly mark it in spec / documentation as legacy and unidiomatic feature with no deprecation. Removing it does no benefit at this point (even if I believe it shouldn't have been there from the very start)
Oct 16 2015
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, 16 October 2015 at 14:07:44 UTC, Dicebot wrote:
 On Friday, 16 October 2015 at 07:00:42 UTC, Jacob Carlborg 
 wrote:
 Yeah, that was the original topic. Then I interpreted it like 
 all uses of "synchronized" would be deprecated.
That would be really bold thing to do, I don't think anyone realistically proposes that. At most I'd suggest to explicitly mark it in spec / documentation as legacy and unidiomatic feature with no deprecation. Removing it does no benefit at this point (even if I believe it shouldn't have been there from the very start)
It wouldn't have no benefit; it would simplify the language. But whether that simplification is worth the breakage it would cause is another matter. And I doubt that Walter and Andrei would go for the idea of deprecating synchronized at this point even if most of us were pushing them for it, because it would break existing code like DWT. Certainly, if we were truly going to discuss deprecating synchronized, we'd have to figure out a way to even get Walter and Andrei to consider it, and I very much doubt that that is going to happen. It wouldn't surprise me if the simple fact that DWT exists would kill that proposal before Walter or Andrei even considered considering it. - Jonathan M Davis
Oct 16 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-10-16 16:07, Dicebot wrote:

 That would be really bold thing to do, I don't think anyone
 realistically proposes that. At most I'd suggest to explicitly mark it
 in spec / documentation as legacy and unidiomatic feature with no
 deprecation. Removing it does no benefit at this point (even if I
 believe it shouldn't have been there from the very start)
Ok, cool. DWT doesn't use synchronized classes so I don't really care :) -- /Jacob Carlborg
Oct 16 2015
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, 16 October 2015 at 18:50:20 UTC, Jacob Carlborg wrote:
 On 2015-10-16 16:07, Dicebot wrote:

 That would be really bold thing to do, I don't think anyone
 realistically proposes that. At most I'd suggest to explicitly 
 mark it
 in spec / documentation as legacy and unidiomatic feature with 
 no
 deprecation. Removing it does no benefit at this point (even 
 if I
 believe it shouldn't have been there from the very start)
Ok, cool. DWT doesn't use synchronized classes so I don't really care :)
Well, you probably will at some point, even if you don't know. According to TDPL, there's not supposed to be any such thing as a class with some functions which are synchronized and some not. The entire class is synchronized or none of it is, and if the class is synchronized then the member variables of the class are not accessible outside of the class. But that hasn't been implemented yet. Instead, we have synchronized functions like in Java. The PR that this thread is about makes it so that the member variables aren't accessible outside of the class, which probably won't cause DWT any problems, since public member variables are generally a bad idea. However, if this PR (or a future PR) actually finishes implementing synchronized classes (I don't know how far this PR actually goes), then any classes that DWT has which have any synchronized functions would then have to be synchronized classes. So, while the current PR may not break DWT, odds are that at some point in the future, synchronized classes will be finished, and DWT will probably break. It wouldn't surprise me if fixing it were fairly easy - particularly if DWT tends to synchronize all of the functions in a class when it synchronizes any of them - but at bare minimum, you're probably going to have to move the synchronized keyword from the function declarations to the class declaration, and it's possible that some of the implementation will have to change to cope with the fact that it's then not legal to have some functions in a class synchronized while others aren't. - Jonathan M Davis
Oct 16 2015
next sibling parent Sean Kelly <sean invisibleduck.org> writes:
On Friday, 16 October 2015 at 21:54:11 UTC, Jonathan M Davis 
wrote:
 [...]
std.concurrency.MessageBox is an example of why you might mix synchronized and non-synchronized data in a class. No methods are synchronized though because it's too blunt an instrument. Synchronization happens internally at the statement level.
Oct 17 2015
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-10-16 23:54, Jonathan M Davis wrote:

 Well, you probably will at some point, even if you don't know. According
 to TDPL, there's not supposed to be any such thing as a class with some
 functions which are synchronized and some not. The entire class is
 synchronized or none of it is, and if the class is synchronized then the
 member variables of the class are not accessible outside of the class.
 But that hasn't been implemented yet. Instead, we have synchronized
 functions like in Java. The PR that this thread is about makes it so
 that the member variables aren't accessible outside of the class, which
 probably won't cause DWT any problems, since public member variables are
 generally a bad idea. However, if this PR (or a future PR) actually
 finishes implementing synchronized classes (I don't know how far this PR
 actually goes), then any classes that DWT has which have any
 synchronized functions would then have to be synchronized classes. So,
 while the current PR may not break DWT, odds are that at some point in
 the future, synchronized classes will be finished, and DWT will probably
 break. It wouldn't surprise me if fixing it were fairly easy -
 particularly if DWT tends to synchronize all of the functions in a class
 when it synchronizes any of them - but at bare minimum, you're probably
 going to have to move the synchronized keyword from the function
 declarations to the class declaration, and it's possible that some of
 the implementation will have to change to cope with the fact that it's
 then not legal to have some functions in a class synchronized while
 others aren't.
Basically all of the usage of the "synchronized" keyword in DWT is actually the synchronized statement. I found a couple of more false positives where "synchronized" was part of a method name. There are cases where not all of the methods contain the synchronized statement. -- /Jacob Carlborg
Oct 18 2015
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, 18 October 2015 at 15:51:50 UTC, Jacob Carlborg wrote:
 On 2015-10-16 23:54, Jonathan M Davis wrote:
 Basically all of the usage of the "synchronized" keyword in DWT 
 is actually the synchronized statement. I found a couple of 
 more false positives where "synchronized" was part of a method 
 name. There are cases where not all of the methods contain the 
 synchronized statement.
Ah. I misunderstood then. I wouldn't expect there to be any changes which would break synchronized statements unless we got rid of synchronized entirely, which is unlikely. - Jonathan M Davis
Oct 18 2015
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2015-10-16 08:49, Dicebot wrote:

 As far as I understand topic is about deprecating direct field access of
 synchronized classes, method calls in synhronized classes and
 `synchronized () {}` blocks will remain untouched.
Is it even possible to do synchronized classes in Java? That is, but synchronized on the class declaration as in D. -- /Jacob Carlborg
Oct 16 2015
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, 16 October 2015 at 07:02:54 UTC, Jacob Carlborg wrote:
 On 2015-10-16 08:49, Dicebot wrote:

 As far as I understand topic is about deprecating direct field 
 access of
 synchronized classes, method calls in synhronized classes and
 `synchronized () {}` blocks will remain untouched.
Is it even possible to do synchronized classes in Java? That is, but synchronized on the class declaration as in D.
I don't think so. synchronized is definitely for functions in Java and C# (and at the moment, D). synchronized classes like TDPL describes don't necessarily conflict with that, but they do force all of the functions in a class to be synchronized, whereas in Java or C#, only a portion of the class may care about or need synchronization. synchronized classes are certainly safer though, since they make it so that you can't get around the mutex without casting. - Jonathan M Davis
Oct 16 2015
prev sibling parent reply Bruno Medeiros <bruno.do.medeiros+dng gmail.com> writes:
On 16/10/2015 08:02, Jacob Carlborg wrote:
 On 2015-10-16 08:49, Dicebot wrote:

 As far as I understand topic is about deprecating direct field access of
 synchronized classes, method calls in synhronized classes and
 `synchronized () {}` blocks will remain untouched.
Is it even possible to do synchronized classes in Java? That is, but synchronized on the class declaration as in D.
No, it's not possible. `synchronized` in Java can only apply to methods, or the synchronized statement. And (for a change), rightly so that it's not possible. This synchronized class feature seems to me a clumsy mis-feature. At first glance at least. -- Bruno Medeiros https://twitter.com/brunodomedeiros
Oct 20 2015
parent Spacen Jasset <spacen razemail.com> writes:
On Tuesday, 20 October 2015 at 18:15:05 UTC, Bruno Medeiros wrote:
 On 16/10/2015 08:02, Jacob Carlborg wrote:
 On 2015-10-16 08:49, Dicebot wrote:

 As far as I understand topic is about deprecating direct 
 field access of
 synchronized classes, method calls in synhronized classes and
 `synchronized () {}` blocks will remain untouched.
Is it even possible to do synchronized classes in Java? That is, but synchronized on the class declaration as in D.
No, it's not possible. `synchronized` in Java can only apply to methods, or the synchronized statement. And (for a change), rightly so that it's not possible. This synchronized class feature seems to me a clumsy mis-feature. At first glance at least.
This change seems like a good idea. As far as having synchronized classes go. I think they can be useful. If, as some of the respondents have said a synchronized class is wrong, then perhaps their classes are too big and indeed require fine grained locks everywhere. Or, if it is performance you are after, then that is the way you might do it. If, however, you would like better defense against multi-threaded related breakage against your non time-critical class, a class wide lock, surely, would be of benefit.
Oct 24 2015
prev sibling parent Sean Kelly <sean invisibleduck.org> writes:
On Friday, 16 October 2015 at 06:49:06 UTC, Dicebot wrote:
 On Friday, 16 October 2015 at 06:26:30 UTC, Jacob Carlborg 
 wrote:
 On 2015-10-15 16:28, Andrei Alexandrescu wrote:

 That may be worrisome. Any information on how many are using 
 DWT, and
 how badly it would break if we pulled the change?

 If we assess there's too much breakage, we can define a DIP 
 and make the
 check opt-in via a flag -dipNN.
I would like to add that the impact of a possible breakage depends on what the alternative is. If a function in Phobos or druntime is provided with the same functionality, then the breakage have less of an impact.
As far as I understand topic is about deprecating direct field access of synchronized classes, method calls in synhronized classes and `synchronized () {}` blocks will remain untouched.
That clarifies things. It seems a fine idea. I can't think of an instance where it would be advisable to have public mutable fields in a synchronized class. Immutable or const though, sure.
Oct 17 2015
prev sibling next sibling parent Kapps <opantm2+spam gmail.com> writes:
On Tuesday, 13 October 2015 at 06:58:28 UTC, Andrei Alexandrescu 
wrote:
 https://github.com/D-Programming-Language/dmd/pull/5188 
 implements a rule defined in TDPL: synchronized classes shall 
 have no public members.

 The motivation behind this limitation is that member accesses 
 in synchronized objects should not occur without some handshake 
 occurring. Public members would make that possible and easy.

 Walter and I are on board with this change. However, it is a 
 breaking change so we want to gather a level of community 
 support before we push the button.


 Thanks,

 Andrei
Ignoring the issue of whether synchronized should actually exist, this makes sense to me. Any class that expects to be thread-safe should not allow public access to fields as that's inherently not thread-safe. Code breakage would exist, but if the user really wants to maintain the same logic, they could just use property in the vast majority of cases.
Oct 13 2015
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 10/13/15 2:58 AM, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/dmd/pull/5188 implements a
 rule defined in TDPL: synchronized classes shall have no public members.
When I first read this, I thought "how the hell will you use this thing then?" Then after reading through most of this thread, I realize you mean public *field* members. Public *method* members are allowed, right? -Steve
Oct 15 2015
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Thursday, 15 October 2015 at 15:20:25 UTC, Steven 
Schveighoffer wrote:
 On 10/13/15 2:58 AM, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/dmd/pull/5188 
 implements a
 rule defined in TDPL: synchronized classes shall have no 
 public members.
When I first read this, I thought "how the hell will you use this thing then?" Then after reading through most of this thread, I realize you mean public *field* members. Public *method* members are allowed, right?
Yes. The idea is that with a synchronized class, all access to the object must be via its member functions so that you can't bypass the mutex that protects the object. Then, because the compiler knows that nothing else can have direct access to the class' member variables and that they're protected by a mutex when inside of a member function, it's able to strip the outer layer of shared from the member variables when you operate on them. So, for basic cases at least, we don't have to cast away shared to operate on shared data - though for more complicated cases (e.g. stuff where stripping off the outer layer of shared isn't enough), you'd still have to cast away shared (though at least, it still encapsulates the shared data on some level in that case). - Jonathan M Davis
Oct 15 2015
prev sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 10/15/15 6:20 PM, Steven Schveighoffer wrote:
 On 10/13/15 2:58 AM, Andrei Alexandrescu wrote:
 https://github.com/D-Programming-Language/dmd/pull/5188 implements a
 rule defined in TDPL: synchronized classes shall have no public members.
When I first read this, I thought "how the hell will you use this thing then?" Then after reading through most of this thread, I realize you mean public *field* members. Public *method* members are allowed, right? -Steve
Right, sorry for the confusion. -- Andrei
Oct 15 2015