【问题标题】:StringBuffer and MultithreadingStringBuffer 和多线程
【发布时间】:2013-01-28 05:58:52
【问题描述】:

StringBuffer 可以通过synchronization 处理多个线程如果您的文本可以更改,并且可以从多个线程访问,请使用 StringBuffer,因为StringBuffer 是同步的。

谁能解释一下多线程什么时候发生?我们是在实现runnable interface or extending Thread class 的程序中创建线程还是基于OS?。

【问题讨论】:

  • Ohoh... 看来您必须先阅读 Java 中的线程。是的,您可以通过实现 Runnable 接口然后启动新线程来启动线程。例如,在 Swing 应用程序中,您通常有多个线程。
  • 在多个线程中正常使用 StringBuffer 是非常罕见的。注意:每个追加都可以以任何顺序发生,因此每个线程只能为必须连续的事情调用一次追加。

标签: java thread-safety stringbuffer


【解决方案1】:

线程可以通过多种方式发生。如果您正在创建线程(例如extends Thread),或者您正在创建传递给某种线程模型的对象(例如implements Runnable),或者即使您只是在某处有处理类似事件的代码(例如回调函数)。如何创建线程并不重要。无论如何,当你有这样的事情时:

public String someMethod()
{
    StringBuilder b = new StringBuilder();
    b.append("Some Method");
    return(b.toString());
}

你知道那是线程安全的。对StringBuilderappend() 方法的任何访问都不需要同步。但是,如果你有这样的东西(只是一个例子):

public class Test
{
    StringBuffer b;

    public Test()
    {
        b = new StringBuffer();
    }

    public String someMethod()
    {
        b.append("Some Method");
        return(b.toString());
    }
}

在这里,您可以看到多个执行“线程”可以调用someMethod(),并且由于它们都将访问StringBuffer,因此需要对其进行同步。可能是在任何给定时间只有一个线程调用该方法,但这种编写方式并不禁止 2 个线程同时调用它。如果使用StringBuilder(不是线程安全的),您可能会遇到问题。

【讨论】:

  • 第一种情况下多线程无法访问,第二种情况怎么会发生。
  • @Kevin 多个线程可以访问第一种方法,当然。但正如您所看到的,每次调用该方法时,它在其范围内都有自己的StringBuilder。所以调用该方法的每个线程都有自己的StringBuilder,而在第二种情况下,所有线程共享​​>一个StringBuffer
  • @Kevin 在StringBuffer 的情况下,或多或少。无论如何,您仍然应该查看 Java 并发文档,尤其是同步部分。
【解决方案2】:

'implementing runnable''extending Thread'

如果资源(此处为StringBuffer)在多个线程(java进程)之间共享/假设StringBuffer定义在非监控范围内(即在synchronize{}块之外)

在这种情况下,多个线程将不会在队列中等待访问StringBuffer 实例,因为没有监视器/或需要获取锁来修改实例。

更多信息java concurrency

【讨论】:

    【解决方案3】:

    假设您的程序不能同时执行两个不同的操作/事件。然后你需要考虑Threads。从逻辑上看,multithreading 表示单个程序的多行。在这种情况下,操作系统将程序视为两个独立且不同的进程

    Java 的创建者慷慨地设计了两种创建线程的方法:implementing an interface and extending a class。一个简单的情况是当您拥有一个日志文件并且多个线程正在记录错误或警告and 写入该日志文件时。

    狗的嗅觉是polymorphic。如果狗闻到猫的气味,它会吠叫并追赶它。如果狗闻到食物的味道,它会流口水并跑到它的碗里。嗅觉在这两种情况下都在起作用。区别在于嗅到的是什么,也就是狗鼻子操作的数据类型!

    让我们用一个例子来潜水:

    // 这是我们的主类。

    class ThreadTest2 {
        public static void main(String args[]){
    
            Thread thread1 = new Thread(new MyClass("thread1: "));
            Thread thread2 = new Thread(new MyClass("thread2: "));
    
            thread1.start();
            thread2.start();
    
            boolean thread1IsAlive = true;
            boolean thread2IsAlive = true;
    
            do {
                if (thread1IsAlive && !thread1.isAlive()) {
                    thread1IsAlive = false;
                    System.out.println("Thread 1 is dead.");
                }
    
                if (thread2IsAlive && !thread2.isAlive()) {
                    thread2IsAlive = false;
                    System.out.println("Thread 2 is dead.");
                }
            } while (thread1IsAlive || thread2IsAlive);
    
        }
    
    }
    

    // 这是我们实现可运行接口的类。

    class MyClass implements Runnable {
        static String message[] = { "Java", "is", "hot,", "aromatic"};
        String name;
    
        public MyClass(String id){
            name = id;
        }
    
        public void run(){
    
            for(int i=0;i<message.length;++i) {
                randomWait();
                System.out.println(name+message[i]);
            }
        }
    
        void randomWait(){
            try {
                Thread.currentThread().sleep((long)(3000*Math.random()));
            } catch (InterruptedException x) {
                System.out.println("Interrupted!");
            }
        }
    }
    

    此程序从 MyThread 类创建两个执行线程 thread1 and thread2。然后它启动两个线程并执行等待线程终止的 do 语句。线程显示 Java 是热的、芳香的。一个字一个字地发送消息,同时在每个字之间等待一小段随机的时间。 Because both threads share the console window,程序的输出标识了哪些线程能够在程序执行期间的不同时间写入控制台。

    【讨论】:

      【解决方案4】:

      您需要通过例如Runnable 接口或Thread 类显式创建额外的Threads,以使多线程成为一个问题。这也适用于某些Java EE 情况,其中JVM 创建额外的线程。

      如果OS 在后台使用额外的线程,负责线程安全的是它而不是你,所以你无需担心。

      您可以在Concurrency section of the Java Tutorials阅读更多内容。

      【讨论】:

        猜你喜欢
        • 2011-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-07-22
        • 2011-02-27
        • 2013-07-02
        • 2011-09-04
        相关资源
        最近更新 更多