Quel est le but de passage de paramètre de bloc synchronisé?
Je sais que
Lorsque vous synchronisez un bloc de code, vous spécifiez l'objet de verrouillage
vous souhaitez utiliser en tant que le verrouillage, de sorte que vous pouvez, par exemple, l'utilisation de certains
la troisième partie de l'objet de la serrure pour ce morceau de code. Qui vous donne
la possibilité d'avoir plus d'une serrure de code de synchronisation dans
un objet unique.
Cependant, je ne comprends pas la nécessité de passer des arguments à la bloquer. Parce qu'il n'a pas d'importance si je passe de la Chaîne d'exemple, Certains aléatoire de la classe de l'instance de la synchronisation de bloc le bloc synchronisé fonctionne parfaitement quel que soit le paramètre passé au bloc.
Donc ma question est si de toute façon synchronisée bloc s'arrête à deux threads d'entrer dans la section critique simultanément. Alors, pourquoi il est nécessaire de passer un argument. (Je veux dire acquérir verrouillage sur certains objet aléatoire par défaut).
J'espère que j'ai encadré ma question correctement.
J'ai essayé l'exemple suivant avec des paramètres aléatoires cours de la synchronisation de bloc.
public class Launcher {
public static void main(String[] args) {
AccountOperations accOps=new AccountOperations();
Thread lucy=new Thread(accOps,"Lucy");
Thread sam=new Thread(accOps,"Sam");
lucy.start();
sam.start();
}
}
À l'aide de non-synchronisée statique bloc:
public class AccountOperations implements Runnable{
private Account account = new Account();
public void run(){
for(int i=0;i<5;i++){
makeWithdrawal(10);
}
}
public void makeWithdrawal(int amount){
String str="asd"
synchronized (str /* pass any non-null object the synchronized block works*/) {
if(account.getAmount()>10){
try{
Thread.sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();
}
account.withdraw(amount);
System.out.println(Thread.currentThread().getName()+" has withdrawn 10, current balance "+ account.getAmount());
}else{
System.out.println("Insufficient funds "+account.getAmount());
}
}
}
}
À l'aide synchronisée statique bloc:
public class AccountOperations implements Runnable{
private static Account account = new Account();
public void run(){
for(int i=0;i<5;i++){
makeWithdrawal(10);
}
}
public static void makeWithdrawal(int amount){
synchronized (String.class /* pass any class literal synchronized block works*/) {
if(account.getAmount()>10){
try{
Thread.sleep(5000);
}catch(InterruptedException e){
e.printStackTrace();
}
account.withdraw(amount);
System.out.println(Thread.currentThread().getName()+" has withdrawn 10, current balance "+ account.getAmount());
}else{
System.out.println("Insufficient funds "+account.getAmount());
}
}
}
}
- double possible de des Éclaircissements sur la signification du paramètre de bloc de synchronisation
- Cela permet d'avoir plusieurs serrures. Sinon, tous les threads sont bloqués lorsque vous ne voulait bloquer une partie spécifique.
- Merci de lire ma question complètement, puis la réponse mentionné dans la question que vous avez spécifié et de décider ensuite.
- Voir aussi stackoverflow.com/questions/133988/...
Vous devez vous connecter pour publier un commentaire.
Synchronisé bloc décide de threads pour arrêter la fonction de l'objet que vous lui transmettez. L'objet que vous passez sert comme l'identifiant de la section critique protégée par l'synchronisé bloc.
Vous pouvez avoir beaucoup de sections critiques dans votre programme, le tout pouvant être exécutées simultanément les uns avec les autres. Par exemple, si vous avez deux indépendants des collections qui doit être accessible simultanément, vous pouvez vous mis en place des sections critiques pour chaque collection. De cette façon, les threads s'être arrêtée que lorsque les autres threads sont déjà accès à la même collection; deux threads différents accès à deux collections différentes serait autorisé à procéder en même temps.
Votre premier exemple est non-trivial. La raison pour laquelle cela fonctionne est que la chaîne de l'objet est initialisé à une chaîne littérale. En raison de littéral du stage, tous les threads de saisir la fonction d'obtenir les mêmes
String
objet, de sorte que le bloc synchronisé correctement garde de la section critique.String.class
objet, qui est le même objet que vous obtenez lorsque vous appelezgetClass()
sur touteString
, est globale pour vos cours d'exécution de la JVM. Il peut être utilisé pour identifier de façon unique un section critique à l'échelle mondiale.java.lang.Class
. Les objets de la classe sont globalement uniques tout au long de la JVM, doncString.class
etRandomClass.class
sont aussi appropriés pour identifier la section critique.Le but du paramètre est double:
Il permet de synchroniser autres blocs sur le même objet, de sorte que si vous avez deux blocs de code qui peut modifier l'état d'un même objet, ils n'interfèrent pas les uns avec les autres.
Par exemple:
Là, il est important que nous synchroniser les deux accède à
list
dans les threads. Nous ne pouvons pas avoir quelque chose d'appeladdValue
et de buter sur la liste, tandis qu'un autre thread appellegetSum
.Il le rend possible pour vous assurer que vous synchronisez avec le bon niveau de granularité. Si vous êtes à sérialiser l'accès à une instance spécifique de la ressource, alors il n'est pas judicieux de le faire dans des instances; vous devriez permettre à plusieurs threads dans le bloc à condition qu'elles soient d'exploitation sur les différentes instances. C'est pourquoi vous synchroniser sur
this
(ou plus généralement un champ dethis
) pour une instance spécifique de la ressource, ou de la classe (ou plus généralement un champ de la classe) si il s'agissait d'une ressource statique. De même, il n'y a pas besoin de synchroniserthis
si vous avez seulement besoin de protéger un domaine spécifique de l'il.Par exemple:
Là, nous synchroniser l'accès à
this.thingyList
surthis.thingyList
, pasthis
ouMyClass.class
. C'est bien si un thread appellegetThingySum
tandis qu'un autre thread appelleaddNifty
, de sorte que la synchronisation sur lesthis
serait exagéré.Re votre
str
exemple:Le commentaire il est incorrect, non
null
instance pas protéger adéquatement le code. La raison ci-dessus semble fonctionner est chaîne de stage: Le mêmeString
exemple, est utilisé par tous les threads, parce que les littéraux de chaîne sont automatiquement placés dans la chaînestagiaire
piscine. (Ce qui signifie que vous avez plus de synchronisation; c'est la JVM de l'échelle, pas spécifique à l'instance.) De sorte qu'il fonctionne, mais pas parce que c'est juste n'importe quel objet. Si vous l'avez modifiée à partir de:à
et synchronisés sur qu'il ne ferait rien pour sérialiser l'accès au compte.
Dans votre exemple, la bonne chose à synchroniser sur est
this.account
.