synchronized block工作不正常

时间:2016-06-11 09:02:48

标签: java multithreading block synchronized

我无法在java中获取同步块

我在下面的帖子中读到了这篇文章,但是并没有完全了解syn-blocks和lock

Synchronized block not working

我不知道为什么下面的代码没有输出A,B,C的统一数组 即使在我同步之后......

    public class synchronizeblock
{
    static StringBuffer s=new StringBuffer();
    public static void main(String []args)
    {
        Threading t1=new Threading(s,'a');
        Threading t2=new Threading(s,'b');
        Threading t3=new Threading(s,'c');
        t1.start();
        t2.start();
        t3.start();     
    }
}
class Threading extends Thread
{
    StringBuffer sb; 
    char ch;

    Threading()
    {

    }
    Threading(StringBuffer sb,char ch)
    {
        this.sb=sb;
        this.ch=ch;
    }
    public void run()
    {
        synchronized(this)   // this(current instance) acts as lock ??
        {
                for(int i=0;i<20;++i)
                {
                    System.out.print(ch);
                }
        }       
    }

}

其中一个输出案例如下:

  

bbbbbbbbbbbbbaccccccccccccccccccccaaaaaaaaaaaaaaaaaaabbbbbbb

我担心的是,一旦一个线程被启动,说一个带有字符'b'的线程(是它的线程 - “一个”)不应该在另一个线程有机会运行之前完成,因为线程“一”被锁定如果错了,请纠正我 我有以下问题

  1. 令人困惑的是“被锁定的东西”和“锁定的东西”。因此,请解释我的代码中确切锁定的内容

  2. 我应该怎么做才能得到统一的输出(在这里说统一输出,我的意思是一旦一个线程开始它的角色应该打印20次)

3 个答案:

答案 0 :(得分:2)

首先StringBuffer

  

字符串缓冲区可供多个线程使用。该   方法在必要时进行同步,以便进行所有操作   在任何特定实例上的行为就像它们出现在某些序列中一样   顺序与方法调用的顺序一致   每个涉及的单个线程。

其余的你可以在问题的底部阅读,但有关不打印我的输出的问题,如A's B's C's,即使当前线程不是完成,你的Thread也会运行为此可以使用join()方法告诉其他线程等到我的工作完成然后去做你的工作所以,你的main方法看起来像这样

      Threading t1 = new Threading(s,'a');
      Threading t2 = new Threading(s,'b');
      Threading t3 = new Threading(s,'c');
      t1.start();
      t1.join();
      t2.start();
      t2.join();
      t3.start();

答案 1 :(得分:0)

使用sb进行同步,因为否则您不会与其他线程同步(您正在为自己锁定对象)。或者创建一个锁定对象,用于在三个不同对象之间进行同步。

public class Threading extends Thread
{
    private Object synchronizationContext;
    private StringBuffer sb; 
    private char ch;

    Threading(StringBuffer sb,char ch, Object synchronizationContext)
    {
        this.sb=sb;
        this.ch=ch;
    }
    public void run()
    {
        synchronized(synchronizationContext)
        {
            for(int i=0;i<20;++i)
            {
                System.out.print(ch);
            }
        }       
    }
}

main对所有人使用相同的synchronizationContext

public static void main(String []args)
{
    Object synchronizationContext = new Object();
    Threading t1 = new Threading(s,'a', synchronizationContext);
    Threading t2 = new Threading(s,'b', synchronizationContext);
    Threading t3 = new Threading(s,'c', synchronizationContext);
    t1.start();
    t2.start();
    t3.start();     
}

答案 2 :(得分:0)

  
      
  1. 真的让人感到困惑的是“锁定什么”和“锁定什么”
  2.   

不确定你在问什么。当我们执行synchronized (obj)时,obj就是被锁定的内容。线程执行锁定,如果另一个线程已经持有锁,则可能会阻塞。说obj“充当锁定”是不恰当的。

synchronized(this)   // this(current instance) acts as lock ??

您锁定了this这就是问题,请参阅下文。

  

2.我应该怎样做才能得到统一的输出(在这里说统一输出

在您的情况下,问题是您在this上进行同步。每个线程都锁定在不同的对象上。如果您希望他们拥有互斥锁以拥有打印其角色的独占权限,那么您需要传入一个他们都锁定的 common 对象:

final Object lock = new Object();
Threading t1 = new Threading(lock,'a');
Threading t2 = new Threading(lock, b');
Threading t3 = new Threading(lock,'c');
...
class Threading extends Thread {
    final Object lock;
    final char ch;
    public Threading(Object lock, char ch) {
       this.lock = lock;
       this.ch = ch;
    }
    public void run() {
        // lock on a common lock object in all 3 threads
        synchronized (lock) {
            for(int i = 0; i < 20; i++) {
                System.out.print(ch);
            }
        }
    }
}