首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同步代码块-练习13-2

同步代码块-练习13-2
EN

Stack Overflow用户
提问于 2017-06-07 18:06:31
回答 2查看 295关注 0票数 0

在本练习中,我们将尝试同步一个代码块。在该代码块中,我们将获得对象的锁,以便其他线程在执行代码块时无法修改它。我们将创建三个线程,它们都将尝试操作同一个对象。每个线程将输出一个字母100次,然后将该字母增加一个。我们将要使用的对象是StringBuffer。我们可以对String对象进行同步,但是一旦创建字符串,就不能修改字符串,因此,如果不生成新的String对象,就无法增加字母。最终的输出应该有100 A,100 B和100 C,所有的线都是不间断的。

  1. 创建一个类并扩展Thread类。
  2. 重写Thread的run()方法。这就是同步代码块的去处。
  3. 为了让三个线程对象共享同一个对象,我们需要创建一个构造函数,在参数中接受一个StringBuffer对象。
  4. 同步代码块将从步骤3获得StringBuffer对象的锁。
  5. 在块中,输出StringBuffer 100次,然后在StringBuffer中增加字母。您可以检查第5章中的StringBuffer (StringBuilder)方法,这些方法将对此有所帮助。
  6. 最后,在main()方法中,使用字母A创建一个StringBuffer对象,然后创建我们类的三个实例并启动所有这三个实例。

解决方案:

公共类OCJPThread扩展线程{

代码语言:javascript
复制
StringBuffer sb;
public OCJPThread(StringBuffer sb) {
    this.sb =sb;
}


public void run(){
    synchronized (sb) {
        System.out.println(Thread.currentThread().getName());
        for(int i=1;i<=100;i++)
            System.out.print(sb);

        System.out.println();
        sb.setCharAt(0, (char)(sb.charAt(0)+1));


    }
}

public static void main(String[] args) {
    StringBuffer sb = new StringBuffer("A");
    OCJPThread t1 =new OCJPThread(sb);
    OCJPThread t2 =new OCJPThread(sb);
    OCJPThread t3 =new OCJPThread(sb);

    t1.start();
    t2.start();
    t3.start();
}

}输出线程-0线程-2线程-1

问:如果我使用的是Stringbuilder或StringBuffer,这并不重要,因为我使用的是同步块。

但是如果我使用同步(这个)而不是字符串缓冲区对象。输出是不可预测的。既然字符串缓冲区已经被同步,为什么我们需要自己来做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-07 18:18:21

StringBuffer是同步的,但只对每个单独的方法调用进行同步。这意味着当您不使用同步时,打印字符串缓冲区值的部分不会在同步块中完成。在此期间,其他线程之一可以更新缓冲区。当这种情况发生时,打印将显示新值。您不能真正知道哪个线程会首先更新缓冲区。

另外,线程可以更改对sb.charAt()的调用和对sb.setCharAt()的调用之间的值。因此,增量本身的结果可能是不可预测的。

注意:this上的同步意味着每个线程在不同的锁上同步,所以它就像根本不同步一样。

票数 0
EN

Stack Overflow用户

发布于 2017-06-07 18:08:20

您正在传递对所有三个线程的相同引用。如果它们在这方面同步,那么它们都可以同时写入StringBuffer。如果它们在公共StringBuffer上同步,那么一次只能访问一个线程。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44419852

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档