进程和线程的区别

进程是指在内存中运行的应用程序,进程有自己独立的堆和栈,既不共享堆也不共享栈,有自己独立的内存空间,一个进程可以有多个线程。
线程是在进程中执行的一个流程,一个进程可以运行多个线程,线程拥有袭击独立的栈和共享内存,共享堆,不共享栈,标准的线程由操作系统调度。
线程同步的5种方法

1、用synchronized关键字同步方法
由于java中每个对象都有一个内置锁,当用关键字synchronized修饰时内置锁将会保护整个方法,在调用该方法之前,需要获取该内置锁,否则将处于阻塞状态。
2、用synchronized关键字同步代码块、
3、用特殊变量Volatile实现线程同步,
<1>Volatile关键字为域变量的访问提供的一种免锁机制。
<2>用Volatile修饰域,相当于告诉虚拟机,该域可能会被其他线程更新。因此每次使用都要重新计算,而不是用寄存器中的值。
<3>Volatile不能保证任何的原子操作,他不能用来修饰final类型的变量。
Volatile 关键字不能保证线程的安全,此关键字用在多线程同步中,可保证读取的可见性,JVM只是保证从主内存加载到线程工作内存的值是最新读取的,而非cache中,但是在多线程对Volatile的写操作时,无法保证线程安全。例如Thread-1和Thread-2在进行read和load操作时,发现主内存中 的count=5,两个线程T1、T2都会加载到最新的值到线程的工作内存中,然后T1对T1堆count进行修改之后,会write到主内存中,此时主内存总的count值为6,。由于T2此时已经read、load加载count=5加载到T2线程的工作内存中,进行运行之后count值w为6,也会write到主内存中,导致主内存中的count值还是6,因此用Volatile修饰之后,还是会存在多线程并发的问题。
4、用重入锁实现线程的同步
在javaSE5.0中新增加了一个java.util.concurrent包来支持同步。ReentrantLock类可重入、互斥、实现了Lock接口的锁,他和synchronized具有相同的基本行为和语义。ReentrantLock类常有的方法有:ReentrantLock()创建一个ReentrantLock的实例,用lock()获得锁,用unlock释放锁,注:用ReentrantLock还可以用构造器创建公平锁的构造方法,但是由于可能大幅度降低程序运行的效率,一般不推荐使用。使用ReentrantLock要及时释放锁,否则会出现死锁,通常在finally中释放锁。

//用重入锁实现线程同步
public class bank{
    private int count = 0;
    //创建锁
    paivate Lock lock = new ReentranLock();
    //存钱
    public void addMoney(int money){
        lock.lock();//上锁
        try{
            count +=money
            }finally{
                lock.unlock;
            }
    }
    //取钱
    public void subMoney(int money){
        if(count - money > 0){
            retrun 
        }
        lock.lock();//上锁
        try{
            count -=money;
        }finally{
            lock.unlock();
        }
    }
    //查询
    public void showMoney(){
        System.out.println("当前的账户余额"+money);
    }
}

5、用局部变量实现线程同步,ThreadLocal。
TheadLocal的原理,若使用ThreadLocal来管理变量,则每一个使用该变量的线程都会获得该变量的一个副本,副本之间相互独立,这样每个线程就可以随意独立的改变自己的变量副本,而不会对其他线程造成影响。

class class bank(){
    private static ThreadLoacl<Integer> count = new ThreadLocal<Integer>(){
        @override
        protected Integer initialValue(){
            retrun 0;
        }
    }
    //存钱
    public void addMoney(int money){
        count.set(count.get()+money);
    }
    //取钱
    public void subMoney(){
        if(count.get() - money < 0){
            return 
        }
        set.count(count.get() - money);
    }
    //查询
    public void showMoey(){
        System.out.println(count.get());
    }
}

用ThreadLocal修饰来维护变量,每个线程运行的都是一个副本,也就是说,存钱和取钱时连个账户,只是名字相同而已。

ThreadLocal和同步机制
ThreadLocal与同步机制都是用来解决多线程中相同变量的访问冲突的问题。
ThreadLocal是用空间换时间,而同步机制使用时间换空间。

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页