簡體   English   中英

Java線程同步問題

[英]java thread synchronization issue

想對線程同步發表一些疑問。 我了解同步的概念。 但是,當我通過多線程實現示例Java程序時,無法達到我想要的結果。 但是最終我可以通過更改一行代碼來實現結果。但是我想知道以下代碼有什么問題。

在這里,當我使用同步塊,synchnonized(SharedResource.class)時,可以達到我想要的結果。 為什么它不適用於同步方法和synced(this)塊?

public class SharedResource {   
    public  synchronized void access(String name){      

            System.out.println(name+" :accessed shared resoure");
            System.out.println(name+" doing his job: ");
            for(int i = 0; i < 5;i++){
                try {
                    System.out.println(name+": "+ i);
                    Thread.sleep(500);
                } catch (InterruptedException e) {              
                    e.printStackTrace();
                }
            }
            System.out.println(name+" :finished doing his job..");

        }
}


public class SharedAccessThread implements Runnable {

    private String name ;
    public SharedAccessThread(String name) {
            this.name = name ;
    }
    @Override
    public void run() {
        SharedResource resource = new SharedResource();
        resource.access(Thread.currentThread().getName());

    }

}



public class MultiThreading {

    public static void main(String[] args) {

        SharedAccessThread thread = new SharedAccessThread(Thread.currentThread().getName());

        Thread t1 = new Thread(thread);
        t1.setName("A");
        Thread t2 = new Thread(thread);
        t2.setName("b");
        Thread t3 = new Thread(thread);
        t3.setName("C");

        t1.start();
        t2.start();
        t3.start();

    }

}

   The expected out put is below:

A :accessed shared resoure
A doing his job: 
A: 0
A: 1
A: 2
A: 3
A: 4
A :finished doing his job..
C :accessed shared resoure
C doing his job: 
C: 0
C: 1
C: 2
C: 3
C: 4
C :finished doing his job..
b :accessed shared resoure
b doing his job: 
b: 0
b: 1
b: 2
b: 3
b: 4
b :finished doing his job..

但是它以混亂的方式給出。 這意味着A可以訪問共享資源。B可以完成我不想要的工作...等等。

問題是您正在每個線程內創建一個new SharedResource

@Override
public void run() {
    SharedResource resource = new SharedResource();
    resource.access(Thread.currentThread().getName());

}

因此,在同步this或在方法本身(這是相同的上同步this )導致每個線程看到一個不同的鎖,所以它沒有效果。

由於類本身對所有線程都是相同的,因此在類本身上進行同步是因為它充當全局鎖,因此可以進行同步。

為了能夠this進行同步,您應該使資源成為靜態成員,例如:

public class SharedAccessThread implements Runnable {

    private String name;
    private static SharedResource resource = new SharedResource();

    public SharedAccessThread(String name) {
            this.name = name ;
    }
    @Override
    public void run() {          
        resource.access(Thread.currentThread().getName());   
    }    
}

這樣可以確保您的所有線程都看到相同的SharedResource實例。

您的代碼不需要同步。 同步在以下位置很重要: Global member and any thread change its values ,但是在示例中不要進行任何互斥。 在Java中,任何線程都有自己的Thread Context ,該Thread Contextlocal variableinput parameter等組成。在您的代碼中,任何線程都有SharedResource實例並調用其access方法,因此不必擔心thread-safety問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM