个人博客
专注IT梦想的地方

java中关于线程安全问题的详细说明

线程安全问题产生的原因:

  1. 多个线程在操作共享的数据。
  2. 操作共享数据的线程代码有多条。

所以,当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。

 

如何来解决线程的安全问题呢?

解决思路:

就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,其他线程就不可以参与运算的。

必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。

 

在java中用同步代码块就可以解决这个问题。

同步代码块的格式:

synchronized(对象){
需要被同步的代码;
}

同步的好处:解决了线程的安全问题。
同步的弊端:相对降低了效率,因为同步外的线程都会判断同步锁。

同步的前提:同步中必须有多个线程并使用同一个锁;

同步函数:同步函数使用的锁是this

同步函数和同步代码块的区别:

同步函数的锁是固定的this

同步代码块的锁是任意的对象。

(建议在以后的开发中使用同步代码块)

静态的同步函数使用的锁是该函数所属字节码文件对象,可以用getClass方法获取,也可以用当前 类名.class 表示。

例如:

class TreadNew implements Runnable {
private int sum=100;
Object obj=new Object();
public void run(){
while(true){
synchronized(obj){//synchronized同时也可以直接放在class TreadNew implements Runnable这个函数中,称为同步函数
if(sum>0){
try{
Thread.sleep(10);
}
catch(InterruptedException e){

}
System.out.println(Thread.currentThread().getName()+”…say…”+sum–);
}
}
}
}
}

public class ThreadAn{
public static void main(String[] args){
TreadNew t=new TreadNew();//创建一个线程
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
Thread t4=new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}

回顾到之前智言有在java中设计模式之一单例设计模式这篇文章中提到关于懒汉式(延迟加载式)单例设计模式存在多线程安全隐患的问题,那么在这里我们将把这个问题进行解决。

原来的程序为:

class Single2{    //类加载进来,没有对象,只有调用了getinstance方法时,才会创建对象(延迟加载形式)
private static Single2 s = null;
private Single2(){}
public static Single2 getInstance(){
if(s==null){
s = new Single2();
}
return s;
}
}

更新为解决了安全隐患后的程序有两种,一种是简单,但是效率低,另外一种则相反。

如下:

第一种:简单、效率低。

class Single{
private static Single s=null;
private Single(){}
public static synchronized Single getInstance(){
if(s==null){
s=new Single();
}
return s;
}
}

 

第二种:稍微复杂,效率高。

class Single{
private static Single s=null;
private Single(){}
public static Single getInstance(){
if(s==null){
synchronized(Single.class){
if(s==null){
s=new Single();
}
}
}
return s;
}
}

赞(0) 打赏
未经允许,不得转载本站任何文章:智言个人博客 » java中关于线程安全问题的详细说明

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏