我无法在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'的线程(是它的线程 - “一个”)不应该在另一个线程有机会运行之前完成,因为线程“一”被锁定如果错了,请纠正我 我有以下问题
令人困惑的是“被锁定的东西”和“锁定的东西”。因此,请解释我的代码中确切锁定的内容
我应该怎么做才能得到统一的输出(在这里说统一输出,我的意思是一旦一个线程开始它的角色应该打印20次)
答案 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)
- 真的让人感到困惑的是“锁定什么”和“锁定什么”
醇>
不确定你在问什么。当我们执行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);
}
}
}
}