线程和进程的区别.
- 进程:操作系统运行程序时分配资源的最小单位,进程和进程之间是相互独立的
- 线程: cpu调度的最小单位,它必须依赖于进程.线程在运行时会占用该进程的部分资源,线程之间是可以共享该进程所拥有的全部资源.但是线程与线程之间也有自己的独立空间,称之为线程私有空间.
Android中进程和线程之间的关系
启动一个App就会启动一个进程,进程名为其包名。一个进程里面会启动多个线程,线程必须依赖进程
多线程引发的问题
- 线程死锁导致进程Anr 原因:因为一个进程中多线程是资源共享的, 也就是都可以访问同一内存地址当中的一个变量;当多个线程在竞争多个资源的时候出现了锁之间的互相等待问题的时候就会死锁
- 比如: 亿如有三个线程,主线程main,和二个子线程A B; 还有二个锁lock1, lock2;二个子线程在跑的时候,假如线程A在执行的时候需要获取锁lock1, 在执行代码时又需要获取锁lock2, 线程B它需要获取锁lock2,在执行代码的时候又需要获取锁lock1.线程A一直在等锁2释放,而线程B一直在等锁lock1释放.这样线程AB就会出现死锁现象,而这时main线程需要lock1或者Lock2的话,这样就一直获取不了,这就主线程就会阻塞.
代码如下:当执行main ()方法时,下面就会出现死锁
Object lock1 = new Object();
Object lock2 = new Object();
private void lockOneM(){
synchronized(lock1){
Thread.sleep(2000);
lockTwoM();
}
}
private void lockTwoM(){
synchronized(lock2){
Thread.sleep(2000);
lockOneM();
}
}
private void main (){
new Thread(() -> {
lockOneM();
}).start();
new Thread(() -> {
lockTwoM();
}).start();
}
解决死锁方法:
上面是争夺资源顺序不对,把lockTwoM方法里面的锁都换成lock1,这样就不存在竞争多个资源了。
创建线程的方式
new Thread(() -> {
}).start();
new Thread() {
@Override
public void run() {
super.run();
}
}.start();
Runnable runnable = new Runnable() {
@Override
public void run() {
}
};
Thread thread = new Thread(runnable);
thread.start();
FutureTask<String> future = new FutureTask<>(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "执行完成";
});
Thread thread1 = new Thread(future);
thread1.start();
try {
//阻塞式
String s = future.get();
} catch (Exception e) {
e.printStackTrace();
}
线程只有执行start()方法才是真正的创建线程
线程生命周期
Runnable runnable = new Runnable() {
@Override
public void run() {
//运行状态
}
};
Thread thread = new Thread(runnable);//创建线程对象
thread.start();//线程处于就绪状态,待cpu时间片轮转到自己
//当cpu时间片轮转到自己,执行run()方法 运行状态
thread.join(); //如果调用这个方法会立马获得执行权直到run()方法执行完才会释放,除非调用yield()方法
thread.yield();//让线程从运行状态调整到就绪状态,待cpu时间片轮转到自己
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
//如果在这里再执行一次话,isInterrupted()会返回true,所以可以使用isInterrupted()这个方法来判断安全退出线程
thread.interrupt()
}
Thread.sleep(10000);//阻塞线程,不会释放锁,不会让出cpu执行权,直到时间到,线程会调整到就绪状态。
thread.interrupt();//调用interrupt()这个方法,会触发sleep()方法的catch里面,但是isInterrupted()这个方法还是会返回false。因为sleep里会重置空上值
try {
synchronized (thread ){
//wait方法,这个是Object内的方法,执行wait()方法会让线程进入到待,释放锁,让出cpu执行权,且一定要加锁,并且锁要是自己
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
//如果在这里再执行一次话,isInterrupted()会返回true,所以可以使用isInterrupted()这个方法来判断安全退出线程
thread.interrupt()
}
synchronized (thread ){
thread.notify();//线程进入到就绪状态,执行wait()后面逻辑。 且一定要加锁,且锁的要是和wait()一样的类
}
//当run()方法执行完,则线程死亡