什么叫线程安全的类
程序员文章站
2022-03-06 15:56:57
在线程安全性的定义中,最核心的概念就是 正确性。当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同(自身已经实现同步),这个类都能表现出正确的行为,那么这个类就是线程安全的。简单说就是:在多线程的运行环境之下,通过一定的同步机制,保证多个线程对同一共享资源的操作能够得到正确的执行,符合这样条件的类称为线程安全的类1.StringBuffer和StringBuilder的区别StringBuffer 是线程安全的StringBu...
在线程安全性的定义中,最核心的概念就是 正确性。当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同(自身已经实现同步),这个类都能表现出正确的行为,那么这个类就是线程安全的。
简单说就是:在多线程的运行环境之下,通过一定的同步机制,保证多个线程对同一共享资源的操作能够得到正确的执行,符合这样条件的类称为线程安全的类
1.StringBuffer和StringBuilder的区别
StringBuffer 是线程安全的
StringBuilder 是非线程安全的
所以当进行大量字符串拼接操作的时候,如果是单线程就用StringBuilder会更快些,如果是多线程,就需要用StringBuffer 保证数据的安全性
非线程安全的为什么会比线程安全的 快? 因为不需要同步嘛,省略了些时间
StringBuffer的append方法
StringBuild的append方法
Demo
在recover前,直接加上synchronized ,其所对应的同步对象,就是this
和hurt方法达到的效果是一样
外部线程访问gareen的方法,就不需要额外使用synchronized 了
package charactor;
public class Hero{
public String name;
public float hp;
public int damage;
//回血
//直接在方法前加上修饰符synchronized
//其所对应的同步对象,就是this
//和hurt方法达到的效果一样
public synchronized void recover(){
hp=hp+1;
}
//掉血
public void hurt(){
//使用this作为同步对象
synchronized (this) {
hp=hp-1;
}
}
public void attackHero(Hero h) {
h.hp-=damage;
System.out.format("%s 正在攻击 %s, %s的血变成了 %.0f%n",name,h.name,h.name,h.hp);
if(h.isDead())
System.out.println(h.name +"死了!");
}
public boolean isDead() {
return 0>=hp?true:false;
}
}
package multiplethread;
import java.awt.GradientPaint;
import charactor.Hero;
public class TestThread {
public static void main(String[] args) {
final Hero gareen = new Hero();
gareen.name = "盖伦";
gareen.hp = 10000;
int n = 10000;
Thread[] addThreads = new Thread[n];
Thread[] reduceThreads = new Thread[n];
for (int i = 0; i < n; i++) {
Thread t = new Thread(){
public void run(){
//recover自带synchronized
gareen.recover();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t.start();
addThreads[i] = t;
}
for (int i = 0; i < n; i++) {
Thread t = new Thread(){
public void run(){
//hurt自带synchronized
gareen.hurt();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
t.start();
reduceThreads[i] = t;
}
for (Thread t : addThreads) {
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for (Thread t : reduceThreads) {
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.printf("%d个增加线程和%d个减少线程结束后%n盖伦的血量是 %.0f%n", n,n,gareen.hp);
}
}
把非线程安全的集合转换为线程安全
ArrayList是非线程安全的,换句话说,多个线程可以同时进入一个ArrayList对象的add方法
借助Collections.synchronizedList,可以把ArrayList转换为线程安全的List。
与此类似的,还有HashSet,LinkedList,HashMap等等非线程安全的类,都通过工具类Collections转换为线程安全的
package multiplethread;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TestThread {
public static void main(String[] args) {
List<Integer> list1 = new ArrayList<>();
List<Integer> list2 = Collections.synchronizedList(list1);
}
}
本文地址:https://blog.csdn.net/weixin_44359566/article/details/107615926