常见概念
进程
每个进程(相当于应用程序)都有独立的代码和数据空间(内存),进程间的切换会有较大开销,一个进程包含1~n个线程。
线程
同一类线程(相当于同一程序的多个窗口)共享代码和数据空间,每个线程都有独立的运行程序和程序计数器。
多进程
操作系统能同时运行多个任务(程序)。
多线程
同一程序中有多个顺序流在执行。
线程的生命周期
实现一个线程的三种方式
第一种方式 继承Thread类
1.让一个类继承Thread类
public class A extends Thread{
//2.重写run()方法
public void run(){
for (int i = 0; i <=40 ; i++) {
//获取当前运行的线程名
String threadName=Thread.currentThread().getName();
System.out.println(threadName+":"+i);
}
}
public static void main(String[] args) {
A a1=new A();
A a2=new A();
//调用start()方法
a1.start();
a2.start();
}
}
1.为什么书写的是run()方法,调用的却是start方法?
答:只有调用了 start()方法,才会表现出多线程的特性,不同线程的 run() 方法里面的代码交替执行。如果直接调用run()方法是面向对象中的方法调用,只有一个线程main,不具备多线程的特性。
2.为什么调用的是start方法,执行的却是run方法?
答:start()方法是线程启动方法,使得线程处于就绪状态等待cpu,当获取到cpu资源后会调用run()方法,交替执行方法中的内容。
3.为什么a1的run方法未执行完毕,a2的run方法就执行了?
答:因为a1和a2是两个线程,会进行资源抢占,谁抢到cpu谁就获取cup资源信息,且每次执行结果都不同。
第二种方式 实现Runnable接口
//创建线程的第二种方法
//①.实现Runnable接口
public class DemoB implements Runnable {
//②.重写run方法
public void run() {
for (int i = 0; i <20 ; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
public static void main(String[] args) {
//这个时候并不是新建状态,并不是一个线程对象
DemoB b1=new DemoB();
DemoB b2=new DemoB();
// 产生2个线程去包装这两个任务b1,b2
// 新建状态
Thread t1=new Thread(b1);
Thread t2=new Thread(b2);
t1.start();
t2.start();
}
}
第三种方式 实现Callable接口
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
//实现一个Callable接口
public class C implements Callable {
//重写call方法,有返回结果
int sum=0;
public Object call() throws Exception{
for (int i = 0; i <= 20; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
sum+=i;
}
return "1-20之和为:"+sum;
}
public static void main(String[] args) throws Exception{
C c1=new C();
C c2=new C();
FutureTask ft1=new FutureTask(c1);
FutureTask ft2=new FutureTask(c2);
Thread t1=new Thread(ft1);
Thread t2=new Thread(ft2);
t1.start();
t2.start();
Object result1=ft1.get();
Object result2=ft2.get();
System.out.println(result1);
System.out.println(result2);
}
}
sychronized关键字
同步锁,有两种使用范围
①方法中加锁,保证线程安全,一次只有一个线程进入
②代码块加锁:sychronized(obj){
//对一段代码块上锁,一次可以有多个线程进入
}
// synchronized关键字的使用场景 同步锁
public class DemoF {
private int count = 10;
// 对当前方法上锁的方式 保证线程安全 场景一
public synchronized