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