线程
线程相关概念
程序:progarm 静态的概念,是计算机指令有序的集合
进程:process 动态的概念,代表程序的依次执行
线程:thread 进程中的一条执行任务的最小单位
进程特点:
1.进程可以并发执行
2.进程是系统进行资源分配的最小单位
3.多个进程间不共享相互的资源,每个进程独享系统分配的资源
4.系统中创建和销毁进程,消耗的资源是比较大的
5.一个进程包含多个线程,至少包含一个线程。
线程特点:
1.线程可以并发执行
2.线程是系统进行运算调度的最小单位
3.对个线程共享一个进程的系统资源,但每个线程又有各自的调用栈、寄存器环境、线程本地存储
4.系统中创建和销毁线程,消耗的资源很小;线程是轻量级进程
5.线程不能独立存在,必须存在于某个进程中
6.进程中的任务都是要靠线程来完成,进程对应的程序中的每一行代码都是要靠某一个线程来执行
7.当一个程序启动的时候,系统为为其创建一个线程。JAVA程序中成为main线程-主线程。(主线程只是因为main的英文意思是才称其为“主线程”的)。主线程执行的路径就是main方法的主体部分
多线程
多线程的优点:
单线程程序问题:一旦线程被阻塞,那么整个进程就被阻塞了,只有解除阻塞,程序才会继续运行。
多线程程序优点:多线程的程序可以被CPU执行的概率更大。若其中一个线程被阻塞,不会影响其他的线程。
线程相关小知识点:
java程序的第一个线程,是main线程–“主线程”,是由JVM创建的。
java.lang.Thread:来描述线程对象的
java创建线程的三种方式
第一种方法:继承Thread类
package com.lyx.io;
/**
* 创建自定义线程的三种方式
* 第一种:继承线程类
* 实现方式:在线程的子类中,重写run方法,run方法的主体就是线程子类对象的任务
*/
public class TestThread {
public static void main(String[] args) {
//创建线程对象
MyThread myThread = new MyThread();
//启动线程
myThread.start();
//main线程也同时打印1-10000
for (int i = 0; i < 10000; i++) {
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
//线程类
class MyThread extends Thread{
//子线程任务打印1-10000
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
//得到当前线程的名字
System.out.println(this.getName()+"--->"+i);
}
}
}
第二种方法:实现Runnable接口
package com.lyx.io;
/**
* 创建自定义线程的三种方式
* 第二种:实现Runnable接口
* 实现方式:定义任务类,在任务类重写run方法,然后把任务交给Thread类的对象去执行
*/
public class TestRunnable {
public static void main(String[] args) {
//创建线程任务类对象
MyRunnable myRunnable = new MyRunnable();
//创建Thread类对象
Thread thread = new Thread(myRunnable);
//启动线程
thread.start();
//main方法线程的for循环,打印1-10000
for (int i = 0; i < 10000; i++) {
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
//线程类 需要实现java.lang.Runnable
class MyRunnable implements Runnable{
//重写run方法
@Override
public void run() {
//子线程任务打印1-10000
for (int i = 0; i < 10000; i++) {
System.out.println(Thread.currentThread().getName()+"--->"+i);
}
}
}
总结两种方式的优缺点
l 继承线程类:优点:比较容易理解,代码实现简单。缺点:多个线程对象共享同一个数据的实现相对复杂。
l 实现Runnable接口:优点:多个线程执行同一个任务,实现比较简单。也就是多个线程共享同一个数据。缺点:相对理解复杂,代码实现相对复杂。
第三种方法:实现Callable接口
package com.lyx.io;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* 创建自定义线程的三种方式
* 第三种:实现Callable接口
* 实现方式:在线程的子类中,重写call方法,call方法的主体就是线程子类对象的任务
*/
public class TestCallable {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//线程类实例化
MyCallable myCallable = new MyCallable();
//创建FutureTask对象,它实现了Runnable接口,用来调度管理线程任务类
FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
//创建Thread对象
Thread thread = new Thread(futureTask);
thread.start();
//输出结果
System.out.println("线程获得结果:"+futureTask.get());//此处throws抛出异常
}
}
//线程类 需要实现java.util.concurrent.Callable
class MyCallable implements Callable<Integer>{
//泛型规定了方法的返回类型
//call方法就是线程任务主体
@Override
public Integer call() throws Exception {
Thread.sleep(500);//休眠500毫秒
//返回0-99随机数
return (int)(Math.random()*100);
}
}
第三种方式和其他的两种方式的区别:
l Call 方法有返回类型,可以根据泛型指定,其他的两种方式,run方法返回类型为void。第三种方式可以任务执行完毕之后,得到一个你想得到的值。通过get去获得该结果。
l run方法的实现中,如果存在有异常产生的内容,那么只能使用try-catch 来处理,不能通过throws 来处理。call 方法定义的时候就抛出了Exception。所以多了一种选择,如果call 方法中存在异常代码,可以不做任何的处理,也就是可以不使用try-catch 来捕获。
线程的生命周期
程的常用方法
未完待续
上一篇: python3 scrapy模拟登陆豆瓣
下一篇: 梦见前女友是什么意思