Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java StringBuffer和多线程_Java_Thread Safety_Stringbuffer - Fatal编程技术网

Java StringBuffer和多线程

Java StringBuffer和多线程,java,thread-safety,stringbuffer,Java,Thread Safety,Stringbuffer,StringBuffer可以通过synchronization处理多个线程。如果文本可以更改,并且可以从多个线程访问,请使用StringBuffer,因为StringBuffer是同步的 有人能解释一下多线程是什么时候发生的吗?我们是在程序中创建线程来实现可运行接口还是扩展线程类,还是基于操作系统?它要么是“实现可运行”要么是“扩展线程” 如果资源(此处StringBuffer)在多个线程(java进程)之间共享/假设StringBuffer定义在非监视范围内(即同步{}块之外) 在这种情况下,

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


有人能解释一下多线程是什么时候发生的吗?我们是在程序中创建线程来实现
可运行接口还是扩展线程类
,还是基于
操作系统

它要么是
“实现可运行”
要么是
“扩展线程”

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

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


有关的更多信息您需要通过
Runnable
接口或
Thread
类显式创建额外的
Thread
s,以便多线程成为关注点。对于某些
javaee
情况也是如此,JVM会创建额外的线程

如果
OS
在后台使用额外的线程,那么线程安全由它负责,而不是由您负责,因此您无需担心


您可以在中阅读更多信息。

线程可以以多种方式发生。如果您正在创建线程(例如,
扩展线程
),或者如果您正在创建传递给某种线程模型的对象(例如,
实现可运行的
),或者即使您只是在某个地方有处理类似事件的代码(例如回调函数)。如何创建线程并不重要。在任何情况下,当你有这样的事情:

public String someMethod()
{
    StringBuilder b = new StringBuilder();
    b.append("Some Method");
    return(b.toString());
}
你知道这是线程安全的。对
StringBuilder
append()
方法的任何访问都不需要同步。但是,如果您有类似的情况(只是一个示例):


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

假设您的程序不能同时执行两个不同的操作/事件。然后您需要考虑
线程
。从逻辑角度来看,
多线程
意味着一个程序的多行。在这种情况下,操作系统将程序视为两个独立且不同的进程

Java的创造者们精心设计了两种创建线程的方法:
实现接口和扩展类。一个简单的例子是,当您有一个日志文件时,多个线程正在记录错误或警告
和写入该日志文件

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

让我们举一个例子:

//这是我们的主课。

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!");
        }
    }
}
//这是我们实现可运行接口的类。

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!");
        }
    }
}
类MyClass实现可运行{
静态字符串消息[]={“Java”、“is”、“hot”、“芳香族”};
字符串名;
公共MyClass(字符串id){
姓名=身份证;
}
公开募捐{

对于(int i=0;iOhoh…似乎您必须首先阅读Java中的线程。是的,您可以通过实现Runnable接口然后启动一个新线程来启动线程。例如,在Swing应用程序中,您通常有多个线程。在多个线程中可能会重复使用StringBuffer。注意:每个附加n以任何顺序发生,因此每个线程只能为必须连续的某个对象调用一次append。为什么在第一种情况下无法访问多个线程,而在第二种情况下会发生这种情况。@Kevin多个线程可以访问第一个方法,当然。但正如您所看到的,每次调用该方法时,它都有自己的
StringBuilder
在其作用域内。因此,调用该方法的每个线程都有自己的
StringBuilder
,而在第二种情况下,在
StringBuffer
的情况下,所有线程或多或少都共享一个
StringBuffer
@Kevin。无论如何,您还是应该看看Java并发文档,特别是关于同步的部分N