如何解决线程安全问题


有2种解决方法。
第一,是采用原子变量,毕竟线程安全问题最根本上是由于全局变量和静态变量引起的,只要保证了对于变量的写操作要么全写要么不写,就可以解决线程安全,定义变量用sig_atomic_t和volatile。
第二,就是实现线程间同步啦,用互斥索,信号量。让线程有序的访问变量就可以啦
在编写一个类时,如果该类中的代码可能运行于多线程环境下,那么就要考虑同步的问题,Java实现线程同步的方法很多,具体如下。
(1)synchronized关键字
     
在Java中内置了语言级的同步原语synchronized关键字,其在多线程条件下实现了对共享资源的同步访问。根据synchronized关键字修饰的对象不同可以分为以下几种情况。
      
*synchronized关键字同步方法
           
public synchronized void 
method(){
                
//do 
something
            
}
          
注意:如果使用synchronized关键字同步方法,很容易误认为同步关键字锁住了它所包围的代码。但是实际情况却不是这样,同步加锁的是对象而并非代码。因此。如果在一个类中有一个同步方法,该方法是可以被两个不同的线程同时执行的,只要每个线程自己创建一个该类的实例即可。
           
示例代码:
package newthread;

public class TestSync {
    
public static void main(String[] args) {
    
    MyThread1 my1=new MyThread1(1);
    
    MyThread1 my2=new MyThread1(3);
    
    my1.start();
        
my2.start();
    }
}
class MyThread1 extends 
Thread{
    private int val;
    public 
MyThread1(int v){
        
val=v;
    }
    public synchronized void 
printVal(int v){
        for(int 
i=0;i<100;i++){
            
System.out.print(v);
        
}
    }
    public void 
run(){
        
printVal(val);
    }
}
    
执行代码结果是1和3交叉输出的,即1和3两个线程在并发执行printVal方法,并没有实现同步功能。原因在于synchronized关键字锁定的是对象而并非代码块,如果需要实现真正的同步,必须同步一个全局对象或者对类进行同步。synchronized关键字同步类的格式如下:
synchronized(MyThread.class){}
改进代码
package 
newthread;

public class TestSync_2 {
    public static 
void main(String[] args) {
        MyThread_2 
my1=new MyThread_2(1);
        
my1.start();
        MyThread_2 my2=new 
MyThread_2(2);
        
my2.start();
    }
}
    class MyThread_2 
extends Thread{
        private int 
val;
        public MyThread_2(int 
v){
            
val=v;
        }
    
    public void printVal(int v){
    
        
synchronized(MyThread_2.class){
        
        for(int 
i=0;i<100;i++){
            
        System.out.print(v);
 

你可能感兴趣的:(android)