欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

什么叫线程安全的类

程序员文章站 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

相关标签: 多线程 java