繁体   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