java线程同步问题

时间:2012-03-03 13:25:33

标签: java multithreading

想对线程同步发表一些疑问。我理解的概念 同步。但是当我通过多线程实现一个示例java程序时,我无法实现我想要的结果。但最后我可以通过更改一行代码来实现结果。但我想知道下面的代码有什么问题。

这里当我使用synchronized块,synchnonized(SharedResource.class)时,我可以实现我想要的结果。 为什么它不适用于同步方法和同步(这个)块?

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..

但它以一种洗牌的方式给出了。这意味着一个访问过的共享资源......做他的工作......等我不想要的。

2 个答案:

答案 0 :(得分:4)

问题是你在每个帖子中创建了一个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的相同实例。

答案 1 :(得分:-1)

您的代码无需同步。同步在以下位置很重要:Global member and any thread change its values,但在您的示例中不要互斥。 在java中,任何线程都有自己的Thread Contextlocal variableinput parameter等组成。 在您的代码中,任何线程都有一个SharedResource实例并调用access方法,因此请不要担心thread-safety问题。

相关问题