Heim >Java >javaLernprogramm >Die Prinzipien und Nutzungsszenarien von Synchronized in Java sowie die Nutzungs- und Differenzanalyse der Callable-Schnittstelle
1. Wenn es häufig zu Sperrenkonflikten kommt, wird es zu einer pessimistischen Sperrung umgewandelt Eine lange, lange Zeit, es wird in eine Schwergewichtssperre umgewandelt.
3 Die Spin-Lock-Strategie, die am häufigsten bei der Implementierung von Leichtgewichtssperren verwendet wird
6. Keine Lese-/Schreibsperre2. Der SperrprozessJVM unterteilt synchronisierte Sperren in sperrenfreie, voreingenommene Sperren, leichte Sperren und schwere Sperren. Es wird je nach Situation nacheinander aktualisiert.Angenommen, der männliche Protagonist ist ein Schloss und der weibliche Protagonist ist ein Thread. Wenn es nur einen Thread gibt, um dieses Schloss zu verwenden, dann erhalten der männliche Protagonist und der weibliche Protagonist keinen Thread Heiratsurkunde (Vermeidung kostenintensiver Operationen), aber die weibliche Protagonistin erscheint und versucht, um die männliche Protagonistin zu konkurrieren, egal wie teuer die Operation, eine Heiratsurkunde zu bekommen, ist Diese Aktion muss abgeschlossen werden, wodurch die weibliche Protagonistin aufgibt
Die Voreingenommenheit besteht nicht darin, zu sperren. Beim „Sperren“ geht es lediglich darum, im Objektheader eine „Sperrvoreingenommenheitsmarkierung“ zu erstellen, um aufzuzeichnen, zu welchem Thread die Sperre gehört Wenn später keine anderen Threads um die Sperre konkurrieren, müssen keine weiteren Synchronisierungsvorgänge durchgeführt werden (wodurch die Notwendigkeit des Hinzufügens von Sperren vermieden wird). Wenn es später andere Threads gibt, die um die Sperre konkurrieren (welcher Thread). Die aktuelle Sperre wurde im Sperrobjekt aufgezeichnet. Es ist leicht zu erkennen, ob der Thread, der die Sperre derzeit anwendet, der zuvor aufgezeichnete Thread ist. Anschließend wird der ursprüngliche voreingenommene Sperrzustand abgebrochen, der in den allgemeinen leichten Sperrzustand übergeht
Callable 和 Runnable 相对, 都是描述一个 "任务". Callable 描述的是带有返回值的任务, Runnable 描述的是不带返回值的任务.Callable 通常需要搭配 FutureTask 来使用. FutureTask 用来保存 Callable 的返回结果. 因为 Callable 往往是在另一个线程中执行的, 啥时候执行完并不确定. FutureTask 就可以负责这个等待结果出来的工作.
代码示例: 创建线程计算 1 + 2 + 3 + ... + 1000, 不使用 Callable 版本
public class Text { static class Result{ public int sum = 0; public Object locker = new Object(); } public static void main(String[] args) throws InterruptedException { Result result = new Result(); Thread t = new Thread(){ @Override public void run() { int sum = 0; for (int i = 0; i <=10000; i++){ sum += i; } result.sum = sum; synchronized (result.locker){ result.locker.notify(); } } }; t.start(); synchronized (result.locker){ while (result.sum == 0){ result.locker.wait(); } } System.out.println(result.sum); } }
代码示例: 创建线程计算 1 + 2 + 3 + ... + 1000, 使用 Callable 版本
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class Text1 { public static void main(String[] args) throws ExecutionException, InterruptedException { Callable<Integer> callable = new Callable<Integer>() { @Override public Integer call() throws Exception { int sum = 0; for (int i = 0; i <=1000; i++){ sum += i; } return sum; } }; //由于Thread不能直接传一个callable实例,就需要一个辅助类来包装 FutureTask<Integer> futureTask = new FutureTask<>(callable); Thread t = new Thread(futureTask); t.start(); //尝试在主线程获取结果 //如果FutureTask中的结果还没生成。此时就会阻塞等待 //一直等到最终的线程把这个结果算出来,get返回 Integer result = futureTask.get(); System.out.println(result); } }
Das obige ist der detaillierte Inhalt vonDie Prinzipien und Nutzungsszenarien von Synchronized in Java sowie die Nutzungs- und Differenzanalyse der Callable-Schnittstelle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!