线程
1.程序、进程、线程
1)程序:是静态的指令集,比如QQ就是一个程序
2)进程:是正在内存中执行的程序,每个进程都是独立的,在内存中都有自己的内存空间
3)线程:一个进程中包括一个或者多个线程,比如在QQ上同时和两个人聊天,那么每个聊天窗口就是一个线程。同一个进程中的线程共享相同的内存地址,访问相同的数据。
单线程:进程中只有一个线程,只做一件事,安全性高,但是效率低。
多线程:进程中有多个线程,同时做多件事,安全性低,但是效率高。
2.多线程的好处
1)提升效率,可以多线程并行。
2)避免线程的阻塞。
3.多线程的执行过程
线程的并发:一个 CPU把自己分割成无数的时间片,每个时间片只能执行一段时间就的交出,多线程的执行其实就是在CPU上不停的来回切换执行,一个线程如果使用完这段时间片,就的交出时间片,等待下一次执行,之所以我们感觉不到线程停止运行是因为CPU运行速度太快我们感觉不到。
线程的并行:可以同时运行多个线程,这需要有多个CPU才能完成。
4.创建线程的方法
1)继承Thread类,并重写Thread中的run方法,然后创建子类的实例,并调用start方法开启线程。
实例:线程模拟两个游戏人物对战
public class threadTest extends Thread {
int blood=100;
@Override
public void run() {
A: for (int i = 0; i < 10; i++) {
blood-=10;
System.out.println(getName()+“被攻击”+"\t"+“blood:”+blood);
if(blood==0) {
System.out.println(getName()+“死亡”);
break A;
}
}
}
}
public class Test {
public static void main(String[] args) {
threadTest t1 = new threadTest();
threadTest t2 = new threadTest();
t1.setName(“赵云”);
t2.setName(“吕布”);
t1.start();
t2.start();
}
}
2)实现Runnable接口,定义类实现Runnable接口,实现run方法;创建实现类实例,在创建Thread实例,然后把实现类实例作为参数,传到Thread实例中
代码演示:
public class runnable implements Runnable {
@Override
public void run() {
System.out.println("线程第二种创建方法");
}
}
public class Test1 {
public static void main(String[] args) {
runnable r = new runnable();
Thread t = new Thread®;
t.start();
}
}
第二种方式的扩展性好,它同时还可以继承其他的类。
5.线程的生命周期:
1)新建:new一个线程
2)就绪:执行start方法
3)运行:运行run方法
4)阻塞:进入阻塞,解除阻塞
5)死亡:run方法结束
6.线程中的方法
1)getName() 返回该线程的名称
2)join() 加塞方法:当前线程停止,等待调用join方法的线程结束后再执行。
3)sleep(毫秒值) 睡眠方法:让线程休息指定时间后,在运行。
4)setDaemon()设置守护线程,让java虚拟机只有守护线程时,虚拟机退出
7.同步代码块,解决多线程并发问题。
当多个线程共同访问共享的数据时,就会出现并发问题。
例如当你去上公共厕所时,一个坑位只能供一个人使用,如果一个人还没有用完,另一个人就进来了,就会出现问题
那么如何解决这个问题呢?
现实生活中解决方案是可以设置一把锁,是当一个人进入后,把门锁上其他人就进不来了,线程中也是这样,如果多线程访问共有数据,那么就设置一个同步锁,关键字是synchronized 可以修饰代码块或方法,被修饰的代码块一旦被某个线程访问,那么其他线程就不能访问。