1.程序和进程的区别
程序就是一种静态概念,就是保存在磁盘上的一系列的文件
而进程是一种动态概念,是运行中的程序,一个程序包括一个或多个进程
2.进程和线程的区别
进程是程序执行相关资源需要使用(CPU、内存、磁盘等)分配的最小单元,进程之间又是相互独立的 拥有自己专属的内存空间,进程又包含一个或多个线程。
线程是CPU资源分配的最小单元,线程需要的资源更少,可以看做是一种轻量级的进程,线程会共享进程中的内存,线程也有独立的空间(栈、程序计数器)线程相互通信更加方便。
3.串行、并行和并发
-
串行---多个指令依次执行
-
并发---每个线程单独执行一段指令,一个cpu在线程间切换(并不是同时执行,而是切换速度过快 )
-
并行---多个CPU内核同时执行多个线程,线程是同时执行的
4. Java几种实现线程的方式
1.继承Thread类
a.重写run方法
b.调用start启动线程
2.实现Runnable接口
a.实现run方法
b.创建实现Runnable接口的对象,传入Thread对象中
c.启动线程
3.实现Callable接口(实现Callable接口可以返回值,继承Thread类和Runnable不行 )
a.实现Callable接口,实现call方法
b.创建Callable对象,传入FutureTask对象
c.创建FutureTask对象,传入Thread对象
d.启动线程
e.调用get方法得到返回结果
4.使用线程池
5.继承Thread和实现Runnable的区别
-
继承Thread类,不能继承其它的类,语法有限制
-
实现Runnable接口,可以继承其它类,语法没有限制
-
Runnalbe接口强制要求实现run方法,不容易出现错误
6.Callable接口
-
实现Callable接口,实现call方法
-
创建Callable对象,传入FutureTask对象
-
创建FutureTask对象,传入Thread对象
-
启动线程
-
调用get方法得到返回结果
7.线程的生命周期
线程几种状态:
-
新建 NEW
-
准备/就绪 START
-
运行 RUNNING
-
阻塞 BLOCKING
-
死亡 DEAD
练习:
1.设计两个线程,一个线程负责打印1~100以内所有的偶数;然后,另外一个线程负责打印1~100以内所有的奇数。测试时,分别设置线程的优先级,观察执行的顺序。
public class Dome1 {
public static void main(String[] args) {
Thread thread1 = new Thread(()->{
for (int i = 1; i <= 100 ; i+=2) {
System.out.println(Thread.currentThread().getName()+"***"+i);
}
});
thread1.start();
Thread thread2 = new Thread(()->{
for (int i = 0; i <= 100 ; i+=2) {
System.out.println(Thread.currentThread().getName()+"***"+i);
}
});
thread1.setPriority(Thread.MIN_PRIORITY);
thread2.setPriority(Thread.MAX_PRIORITY);
thread2.start();
}
}
2.实现一个线程,用于扫描某个目录下的所有文本文件(包括:java、txt、html),并将文字内容打印出来。
public class Dome2 {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
find( "/d:/vue");
});
thread.start();
}
static void find(String path) {
//读取到路径下的file
File file = new File(path);
//获取当前file下的所有文件和目录
File[] files = file.listFiles();
//判断当前file是否为空
if (files != null) {
//遍历
for (File f : files) {
//判断是否为文件 是的话 输出
if (f.isFile()) {
System.out.println(f.getName());
} else {
find(f.getAbsolutePath());
}
}
}
}
}
3.某人正在看电视连续剧,从第1~88集,看到第10集时,来了一个送快递的,收完快递后后,继续看电视。
public class Dome3 {
public static void main(String[] args) {
new Thread(()->{
for (int i = 0; i <89 ; i++) {
System.out.println(Thread.currentThread().getName()+"看到了第"+i+"集");
try{
Thread.sleep(300);
}catch (InterruptedException e){
e.printStackTrace();
}
if (i == 10){
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"==="+"送快递的来了");
try{
Thread.sleep(5000);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"==="+"快递拿完了");
}
});
t1.start();
try{
t1.join();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}).start();
}
}
4.多线程模拟龟兔赛跑:
乌龟和兔子进行1000米赛跑,兔子前进5米,乌龟只能前进1米。
但兔子每20米要休息500毫秒,而乌龟是每100米休息500毫秒。
谁先到终点就结束程序,并显示获胜方
public class Dome4 {
public static void main(String[] args) {
Result r = new Result();
new Thread(() -> {
for (int i = 1; i <= 1000; i++) {
System.out.println("乌龟跑了" + i + "米");
try {
Thread.sleep(1);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if (i >= 1000) {
r.isWin = true;
System.out.println("乌龟胜利了" + i);
break;
}
if (i % 100 == 0) {
try {
System.out.println("乌龟在"+i+"米处开始休息");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(() -> {
int m = 0;
for (int j = 1; j <= 200; j++) {
if(r.isWin){
System.out.println("兔子跑了" + m + "米............");
break;
}
m += 5;
System.out.println("兔子跑了" + m + "米");
try {
Thread.sleep(1);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if (m >= 1000) {
System.out.println("兔子胜利了" + j);
}
if (m % 20 == 0) {
try {
System.out.println("兔子在"+j*5+"米处开始休息");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
class Result{
boolean isWin = false;
}
线程常用方法:
start() | 启动 |
stop() | 停止(有可能会导致死锁的问题),停止线程的话 可以让run执行结束 |
String getName() | 可以获得线程的名字 |
setName(String) | 设置线程的名字 |
sleep(long) | 进入睡眠(毫秒数) |
setPriority(int) | 设置线程的优先级 优则抢占CUP几率更大(1-10为等级) |
setDaemon(boolean) | 设置为后台线程 true ,后台线程就是为其它线程服务的,如果没有其它线程存在,就自动死亡消失; |
join() | 线程的加入(合并)让其它线程先执行完,再执行自己的指令 |