同步块不能正常工作

synchronized block is not working quite right

我无法在 java

中获取同步块

我在 post 之后阅读了这篇文章,但不太了解同步块和锁

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' 的线程(可以是线程-"one")它不应该在另一个线程有机会 [=42 之前完成吗? =] 因为线程 "one" 锁定了对象,如果错了请纠正我 我有以下问题

  1. 真是把"what gets locked"和"what acts as lock"搞混了。那么请解释一下我的代码中到底锁定了什么

  2. 我应该怎么做才能获得统一输出(这里说统一输出,我的意思是一旦线程启动,它的字符应该打印 20 次)

使用 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();     
}

首先StringBuffer

String buffers are safe for use by multiple threads. The methods are synchronized where necessary so that all the operations on any particular instance behave as if they occur in some serial order that is consistent with the order of the method calls made by each of the individual threads involved.

其余的你可以在你的问题底部阅读但是关于不打印我的输出的问题 A's B's C's 它是你的 Threads 运行 即使当前线程不是finish 因为它可以使用 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. it's really confusing "what gets locked" and "what acts as lock"

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

是不恰当的
synchronized(this)   // this(current instance) acts as lock ??

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

2.and what should i do to get uniform output (by saying uniform output here

在您的情况下,问题是您在 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);
            }
        }
    }
}