[英]Java Thread synchronization - Thread.sleep() Method Not Working as desired
我聽說,sleep()將鎖定當前的sync方法/塊但是在這里,當我在線程1上調用sleep()時,線程2能夠訪問同一個塊嗎? 誰能解釋一下嗎?
public class Main {
public static void main(String args[])
{
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
}
================================================== ===================
public class Thread1 extends Thread{
public void run() {
Syncc s1 = new Syncc();
s1.me("T1:");
}
}
================================================== ===================
public class Thread2 extends Thread{
public void run() {
Syncc s2 = new Syncc();
s2.me("T2:");
}
}
================================================== ===================
public class Syncc{
public void me(String s){
synchronized(this){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
==========================================
going to start t1
going to start t2
T2: 0
T1: 0
T2: 1
T1: 1
T1: 2
T2: 2
T1: 3
T2: 3
T1: 4
T2: 4
T2: 5
T1: 5
但是根據sleep()方法,它不應該解鎖當前的同步塊嗎? 如果是這樣,輸出應該是......
將開始t1開始t2
T1: 0
T1: 1
T1: 2
T1: 3
T1: 4
T1: 5
T2: 0
T2: 1
T2: 2
T2: 3
T2: 4
T2: 5
我的意思是在線程1執行后,只有線程2應該正確啟動? 問題是什么?
這是因為您在此處有兩個不同的Syncc
實例。 每個線程都有自己的Syncc
副本。
嘗試對單個實例執行相同操作。 您還可以在靜態上下文中進行同步並嘗試。
為了模擬,修改Thread1
和Thread2
接受的一個實例Syncc
。
public class Thread1 extends Thread {
private Syncc syncc;
public Thread1(Syncc syncc) {
this.syncc = syncc;
}
public void run() {
this.syncc.me("T1:");
}
}
然后您可以這樣啟動它們:
public static void main(String args[]) {
Syncc syncc = new Syncc();
Thread1 t1 = new Thread1(syncc);
Thread2 t2 = new Thread2(syncc);
System.out.println("going to start t1");
t1.start();
System.out.println("going to start t2");
t2.start();
}
睡眠,產量和加入規則
休眠用於延遲執行一段時間,並且當線程進入休眠狀態時不釋放鎖定。
保證睡眠線程至少在sleep()方法的參數中指定的時間內休眠(除非它被中斷), 但不能保證新喚醒的線程何時實際返回運行狀態。
sleep()方法是一個靜態方法,它休眠當前正在執行的線程的狀態。 一個線程無法告訴另一個線程睡眠。
setPriority()方法用於Thread對象,為線程提供1(低)到10(高)之間的優先級,雖然不保證優先級,並且並非所有JVM都能識別10個不同的優先級 - 某些級別可以被視為有效等於。
如果未明確設置,則線程的優先級將與創建它的線程的優先級具有相同的優先級。
如果存在具有相同優先級的可運行線程,則yield()方法可能會導致正在運行的線程退出。 無法保證會發生這種情況,並且無法保證在線程退出時會選擇運行不同的線程。 線程可能會產生然后立即重新進入運行狀態。
最接近保證的是,在任何給定時間,當線程運行時,它通常不會比可運行狀態中的任何線程具有更低的優先級。 如果在高優先級線程進入runnable時正在運行低優先級線程,則JVM通常會搶占正在運行的低優先級線程並將高優先級線程置於其中。
當一個線程調用另一個線程的join()方法時,當前運行的線程將一直等到它加入的線程完成。 想想join()方法就是這樣說的,“嘿線程,我想加入到你的最后。讓我知道你什么時候完成,所以我可以進入runnable狀態。”
http://www.amazon.com/SCJP-Certified-Programmer-Java-310-065/dp/0071591060
您已創建兩個Synch對象,每個對象對應一個線程。 每個對象都有自己的副本。 因此,當你啟動每個線程時,使用run方法線程正在調用它自己的函數副本。 由於兩個線程只在它們的副本上起作用,因此它就像一個單線程場景。 如果您確實想測試多線程場景,那么請將該方法設為靜態(類級方法)並應用類級鎖。
Thread1.java
public class Thread1 extends Thread{
public void run() {
Syncc.me("T1:");
}
}
Thread2.java
public class Thread2 extends Thread{
public void run() {
Syncc.me("T2:");
}
}
Syncc.java
public class Syncc{
public static void me(String s){
synchronized(Syncc.class){
for(int i=0; i<=5; i++)
{
System.out.println(s+" "+" "+i);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.