目录
一、进程与线程
二、进程与线程的区别
三、线程的实现
四、线程的生命周期
五、线程小练习
总结以上就是今天要讲的内容,本文仅仅简单介绍了线程的使用,而线程还有很多常用的函数和方法。且听下回分解。
一、进程与线程
1.进程的概念:进程就是正在进行的程序,他会占用对应的内存区域,由CPU执行与计算。
2.线程的概念:线程是操作系统OS能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.
一个进程可以开启多个线程,其中有一个主线程来调用本进程中的其他线程。
我们看到的进程的切换,切换的也是不同进程的主线程
多线程可以让同一个进程同时并发处理多个任务,相当于扩展了进程的功能。
二、进程与线程的区别
从java内存区域上来说,线程在堆和方法区是线程共享的,本地方法栈、虚拟机栈和程序计数器是线程私有的。
-
根本区别:进程是操作系统资源分配的基本单位,线程是处理器任务调度和执行的基本单位。内存中运行的每个.exe程序都是一个进程。
-
资源开销:进程开销大,但是资源的管理和保护好;而线程是资源开销小,但是不利于资源的管理和保护。
-
一个进程包含至少一个线程,也可以包含多个线程,各个进程是相互独立的,而线程不一定,同一个进程中的线程可能相互影响。
三、线程的实现
1.继承Thread类
class MyThread extends Thread {
public void run(){
for (int i=0;i<100;i++){
System.out.println(MyThread.currentThread().getName()+"执行了"+i);
}
}
}
class ThreadDemo{
public static void main(String[] args) throws InterruptedException {
MyThread mythread = new MyThread();
MyThread mythread1 = new MyThread();
mythread.start();
for (int i=0;i<100;i++){
System.out.println(MyThread.currentThread().getName()+"执行了"+i);
}
mythread1.start();
}
}
2.Runnable接口
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i=0;i<100;i++){
System.out.println(MyThread.currentThread().getName()+"--"+i);
}
}
}
class RunnableDemo{
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
}
}
3.Callable接口
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; class MyCallable implements Callable{ @Override public Long call() throws Exception { long sum = 0; for (long i = 0;i<1000000000L;i++){ sum += i; } return sum; } } class CallableDemo{ public static void main(String[] args) { FutureTask tasK = new FutureTask<>(new MyCallable()); Thread thread = new Thread(tasK); thread.start(); System.out.println("----等待结果----"); try { System.out.println(tasK.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
4.线程池
线程池其实就是一个 容纳多个线程的容器 ,其中的线程可以反复使用,省去了频繁创建线程对象的操作 ,无需反复创建线程而消耗过多资源。
四、线程的生命周期
线程的生命周期会经历以下几个状态:
新建:new创建线程对象时
就绪:调用 start()方法时
运行:调用 run()方法时
阻塞: 多种原因可导致阻塞如(sleep,执行IO操作,wait等)
死亡:执行完run后
五、线程小练习
1.设计两个线程,一个线程负责打印1~100以内所有的偶数;然后,另外一个线程负责打印1~100以内所有的奇数。测试时,分别设置线程的优先级,观察执行的顺序。
class Zy1 {
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.实现一个线程,用于扫描某个目录下的所有文本文件(包括:java、txt、html),并将文字内容打印出来。
public class Zy2 {
public static void main(String[] args) {
new Thread(() -> {
File file = new File("D:\Study\aaa.txt");
readFile(file);
}).start();
}
public static void readFile(File f) {
if (f.isDirectory()) {
File[] files = f.listFiles();
if (files != null) {
for (File file : files) {
readFile(file);
}
}
} else {
System.out.println(f.getName());
//读文件
try {
//得到文件
//得到文件读取的字符流
FileReader fileReader = new FileReader(f);
//得到带缓冲字符流
BufferedReader bufferedReader = new BufferedReader(fileReader);
String readLine = null;
while((readLine = bufferedReader.readLine()) != null){
System.out.println(readLine);
}
fileReader.close();
bufferedReader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3.某人正在看电视连续剧,从第1~88集,看到第10集时,来了一个送快递的,收完快递后后,继续看电视。
public class Zy3 {
public static void main(String[] args) {
new Thread(() -> {
for (int i = 1; i < 89; i++) {
System.out.println(Thread.currentThread().getName() + "--" + "看到了第" + i + "集");
try {
Thread.sleep(300);
} catch (InterruptedException e1) {
e1.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 Zy4 {
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;
}



