1.进程和线程
1.1.进程和线程
1.操作系统中运行多个软件
2.一个运行中的软件可能包含多个进程
3.一个运行中的进程可能包含多个线程
1.2.CPU线程和操作系统线程
1.2.1.CPU线程
1.多核CPU的每个核各自对立运行,因此每个核一个线程
2.「四核⼋线程」:CPU硬件方在硬件级别对CPU进行了一核多线程的支持(本质上依然是每个核一个线程)
1.2.2.操作系统线程
1.操作系统利用时间分片的方式,把CPU的运行拆分给多条运行逻辑,即为操作系统的线程。
2.线程使用
2.1.Thread和Runnable
//Thread
Thread thread = new Thread(){
@Override
public void run() {
Log.e("TAG","Thrad started------Thread");
}
};
thread.start();
//Runnable
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.e("TAG","Thrad started------Runnable");
}
};
Thread thread1 = new Thread(runnable);
thread1.start();
2.2.Executor 和线程池
常用:newCachedThreadPool()
//Executor
Runnable runnable = new Runnable() {
@Override
public void run() {
Log.e("TAG","runnable----------------------");
}
};
Executor executor = Executors.newCachedThreadPool();
executor.execute(runnable);
executor.execute(runnable);
executor.execute(runnable);
3.线程同步与线程安全
3.1.synchronized方法
private synchronized void count(int newValue) {
x = newValue;
y = newValue;
if (x != y) {
System.out.println("x: " + x + ", y:" + y);
}
}
问题:
当我们两个线程同时调用count方法,如果不添加synchronized关键字,会出现x!=y的情况。
因为当线程1执行到count方法的x=newValue,突然切换时间片切换到线程2执行到y = newValue,此时x就会不等于y,此时就会出现数据问题,数据不同步问题。
解决:
添加synchronized关键字后,会把count方法作为一个整体,当线程1的count方法未执行行完成,此时其他线程执行count方法,此时线程1还持有锁,线程2只能等待线程1执行完成后才能执行count方法。保证数据同步问题。
3.2.synchronized代码块
private void count(int newValue) {
synchronized(this){
x = newValue;
y = newValue;
if (x != y) {
System.out.println("x: " + x + ", y:" + y);
}
}
}
synchronized关键字的本质:
1.保证方法内部或代码块内部资源(数据)的互斥访问,即同一时间,由同一个Monitor(可认为是synchronized关键字)监视的代码,最多只能有一个线程在访问。
2.保证线程之间对监视资源的数据同步,即,任何线程在获取到Monitor后的第一时间,会先将共享内存中的数据复制到自己的缓存中,任何线程在释放Monitor的第一时间会先将缓存中的数据复制到共享内存中。
volatile关键字
1.保证加了volatile关键字的字段的操作具有原子性和同步性,其中原子性相当于实现了针对单一字段的线程间互斥访问,因此volatile可以看做是简化版的synchronized
2.volatile关键字只对基本类型(byte,short,int,long,char,float,double,boolean)的赋值操作和对象的引用赋值操作有效。
4.总结
4.1.线程安全问题的本质:
在多个线程访问共同的资源时,在某一个线程对资源进行写操作的中途(写入已经开始,但还没结束),其他线程对这个写了一半的资源进行了读操作,或者基于这个写了一半的资源进行了写操作,导致数据出现错误。
4.2.锁机制的本质:
1.通过对共享资源进行访问限制,让同一时间只有一个线程可以访问资源,保证了数据的准确性。
2.不论是线程安全问题,还是针对线程安全问题所衍生出的锁机制,他们的核心都是在共享的资源,而不是在某个方法或者某几行代码。
网友评论