文章目录
- 前言
-
目录
一、线程是什么?
二、线程与程序的区别
1.程序
2.线程
三、线程实现方式
四 、串行,并行,并发
五、线程常用方法
六、案例
总结
一、线程是什么?
目录
一、线程是什么?
二、线程与程序的区别
1.程序
2.线程
三、线程实现方式
四 、串行,并行,并发
五、线程常用方法
六、案例
总结
一、线程是什么?
首先来了解线程在程序运行中的具体位置,例qq.exe运行流程图:
二、线程与程序的区别
1.程序
1.程序
程序:是一种静态资源,保存在磁盘上,一个程序运行包含一个或多个进程。多个进程相互独立,有自己的内存空间。
进程:是动态资源,用来请求程序运行的各种资源(cpu,内存,声卡......),是程序执行相关资源的最小单位。 一个进程包含一个或多个线程。多个线程共享进程中的内存,每个线程也会有独立的内存(栈,程序计数器)
2.线程
线程: 是cpu分配资源的最小单位,需要的资源更少,可以看成是轻量的进程,相互通信更方便。
三、线程实现方式
线程实现有四种方式:
1.继承THread。(Java只支持单继承)
public class Demo {
static class MyTread extends Thread{
public void run(){
for (int i = 0; i <100 ; i++) {
System.out.println(currentThread().getName()+"执行"+i);
}
}
}
public static void main(String[] args) {
MyTread myTread = new MyTread();
for (int i = 0; i <100 ; i++) {
System.out.println(Thread.currentThread().getName()+"执行"+i);
}
}
}
2. 实现Runnable接口。(Java可以实现多个接口)
public class Demo2 {
static class MyRunnable implements Runnable{
@Override
public void run() {
for (int i = 0; i <100 ; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
}
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread =new Thread(myRunnable);
thread.start();
}
}
3.实现Callable接口 。(get()方法获得返回值)
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Demo3 {
static class MyCallable implements Callable{
@Override
public Long call() throws Exception {
long sum=0;
for (long i = 0; i <1000000000L ; i++) {
sum+= i;
}
return sum;
}
}
public static void main(String[] args) {
FutureTask task = new FutureTask<>(new MyCallable());
Thread thread = new Thread(task);
thread.start();
try {
System.out.println(task.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
4.线程池
一个线程的生命周期:创建,就绪,运行,阻塞,死亡。如下图:
四 、串行,并行,并发
串行:多个线程依次执行。
并行:多个线程来回切换执行。(并不是在同一时间执行多个线程)
并发:多核cpu,同时执行多个线程。
五、线程常用方法
| 方法 | 介绍 |
|---|---|
| start() | 启动线程 |
| stop() | 停止(禁用) |
| String getName() | 获得执行线程的名字 |
| setName(String) | 设置执行线程名字 |
| sleep(long) | 进入睡眠,毫秒(会执行其它线程) |
| setPriority(int) | 设置线程的优先级(1~10从低到高)越高抢CPU几率更高(并不是谁的优先级高就一定先执行) |
| setDaemon(boolean) | 设置为后台线程 true ,后台线程是为其它线程服务的,如果没有其它线程存在,就自动死亡;使用案例:GC就是一种后台线程 |
| join() | 线程的加入(合并)让其它线程先执行完,再执行自己的指令(线程启动后生效) |
六、案例
自己实现了了四个小案例
1.
public class Task {
// 设计两个线程,一个线程负责打印1~100以内所有的偶数;然后,另外一个线程负责打印1~100以内所有的奇数。
//
// 测试时,分别设置线程的优先级,观察执行的顺序。
public static void main(String[] args) {
new Thread(()->{
for (int i = 0; i <100 ; i++) {
if(i%2==0){
System.out.println(Thread.currentThread().getName()+"偶数--"+i);
}
}
}).start();
new Thread(()->{
for (int i = 0; i <100 ; i++) {
if(i%2!=0){
System.out.println(Thread.currentThread().getName()+"奇数--"+i);
}
}
}).start();
}
}
2.
public class Task2 {
// 某人正在看电视连续剧,从第1~88集,看到第10集时,来了一个送快递的,收完快递后后,继续看电视。
public static void main(String[] args) {
new Thread(()->{
for (int i = 1; i <88 ; i++) {
System.out.println("看电视看到了"+i+"集");
if(i==10){
new Thread(()->{
System.out.println("拿快递");
}).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
3.
import java.io.*;
public class Task3 {
// 实现一个线程,用于扫描某个目录下的所有文本文件(包括:java、txt、html),并将文字内容打印出来。
public static final String PATH="D:\test";//路径常量
public static void main(String[] args) {
new Thread(()->{
File file = new File(PATH);
findFile(file);
}).start();
}
public static void findFile(File file) {
if(file.isDirectory()){//是否为目录
File[] files = file.listFiles();//得到目录下所有文件集合
if(files!=null){
for (File file1 : files) {
findFile(file1);//递归
}
}
}else {
System.out.println(file.getName());//输出文件名
try(FileReader reader = new FileReader(file);
BufferedReader br = new BufferedReader(reader) ){//创建文件缓存流
String sb;//定义字符串
while ((sb=br.readLine())!=null){//读取到的行不为空
System.out.println(sb);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
4.
public class Task4 {
public static void main(String[] args) {
// 多线程模拟龟兔赛跑:
// 乌龟和兔子进行1000米赛跑,兔子前进5米,乌龟只能前进1米。
// 但兔子每20米要休息500毫秒,而乌龟是每100米休息500毫秒。
// 谁先到终点就结束程序,并显示获胜方
Result r = new Result();//自定义内部类
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();
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();
}
static class Result{
boolean isWin = false;
}
}
总结
多看多练习。



