JavaSE学习笔记 Day21
个人整理非商业用途,欢迎探讨与指正!!
<< 上一篇
文章目录
- [JavaSE学习笔记 Day21](#JavaSE学习笔记 Day21)
···
十八、多线程
18.1多线程概念
进程:程序是静态的,真正运行起来的程序被称之为进程
线程:轻量级的进程,每个程序都有固定的顺序向下执行,同时被电脑的CPU进行调度的,进程有多个线程组成,每个线程之间完成不同的工作,交替执行,被称之为多线程
百度网盘就一个进程,可以同时控制多个上传和下载的任务。
Java中的JVM是一个进程,main方法就是进程中的主线程,可以通过创建线程对象独立于主线程之外并发的执行(异常处理就是独立线程的)
18.2线程的组成
CPU时间片
运行的数据
线程中的逻辑代码
18.3线程的创建
java中是支持多线程的,提供多种创建线程的方式
两种基本的:
1.继承Thread类
2.实现Runnable接口
18.3.1继承Thread类
java
// 继承Thread类
public class MyThread extends Thread{
// 若自定义线程功能代码,需要重写run方法
// run就是一个普通的方法,在线程启动时,由线程自动的调用
@Override
public void run() {
for(int i = 1;i<=100;i++) {
System.out.println("我是线程中的数值:"+i);
}
}
public static void main(String[] args) {
// main就是一个线程对象,该对象由JVM调用,main线程无需启动
// 创建线程对象
MyThread m1 = new MyThread();
// 我们的线程需要启动
m1.start();
// run就是一个普通方法
// m1.run();
for(int i = 1;i<=100;i++) {
System.out.println("我是主线程中的数值:"+i);
}
}
}
18.3.2实现Runnable接口
Runnable本身不是线程,只是实现了该接口的类有了线程的特性
java
// 实现Runnable
public class MyRunnable implements Runnable {
@Override
public void run() {
for(int i = 1;i<=10;i++) {
System.out.println("我的线程:"+i);
}
}
public static void main(String[] args) {
// 创建实现类对象
MyRunnable my1 = new MyRunnable();
// 借助于Thread类,进行启动
// 创建线程对象
Thread t1 = new Thread(my1);
// 启动
t1.start();
for(int i = 1;i<=10;i++) {
System.out.println("main:"+i);
}
}
}
18.3.3两种创建线程的区别
创建方式不同
继承Thread类之后的子类本身就是线程了,可以直接使用start进行启动
实现Runnable接口实则是代理模式的,仍然需要交给Thread类进行线程的启动操作
实际应用中实现Runnable方式创建线程的方式会多一些,因为Java是单继承的
设置线程名字的方式不同
java
public class Test01 {
public static void main(String[] args) {
// 每个线程都是默认的名字
MyThread m1 = new MyThread("线程1");
System.out.println(m1.getName());
Thread t1 = new Thread(new MyRunnable(),"线程2");
System.out.println(t1.getName());
}
}
18.4线程启动时一定要注意的问题★★★★☆
run只是一个普通方法
线程的启动使用start方法
线程启动后会自动的调用run方法
一个线程只能start一次
18.5线程的基本状态
初始状态:线程对象被创建(new线程对象),只在堆中开辟空间,和常规对象没有任何的区别
就绪状态:调用start方法时就进入了就绪状态,等待CPU时间片的选中
运行状态:获取时间片之后,进入了运行状态,若时间片到期了,就回到就绪状态
终止状态:主线程或者独立线程的run方法执行完毕类,就进入到终止状态,并会释放持有的时间片
18.6线程的常用方法
java
// 和线程名字相关的方法
public class Test02 {
public static void main(String[] args) {
// String str = null;
Thread t1 = new Thread("线程1");
// 获取线程名的方法
System.out.println(t1.getName());
// 设置线程名
t1.setName("Thread------0");
System.out.println(t1.getName());
// 查看当前执行的线程
// 查看当前main线程
System.out.println(Thread.currentThread());
// A的默认为就是Thread-0
A a = new A();
a.setName("AAAA");
a.start();
// a.run();//run就是普通方法,若使用线程调用,就是main在调用,若使用start才是对应的线程对象
}
}
class A extends Thread {
@Override
public void run() {
// 在A线程中执行,查看的就是A线程
System.out.println(Thread.currentThread());
}
}
java
public class Test03 {
// 线程优先级相关方法
// 从1~10的级别,默认的优先级都5,main的优先级同样是5但是main线程本身就比其他线程的优先级要高
// 优先级高不代表这一定先执行
public static void main(String[] args) {
BThread t1 = new BThread("1111");
t1.setPriority(Thread.MIN_PRIORITY);//静态常量就是看着更直观,知道是最小的优先级
BThread t2 = new BThread("2222");
t2.setPriority(Thread.MAX_PRIORITY);
BThread t3 = new BThread("3333");
t3.setPriority(3);
BThread t4 = new BThread("4444");
t4.setPriority(7);
t1.start();
t2.start();
t3.start();
t4.start();
for(int i = 1;i<=10;i++) {
System.out.println(Thread.currentThread().toString()+":"+i);
}
}
}
class BThread extends Thread {
@Override
public void run() {
for(int i = 1;i<=10;i++) {
System.out.println(Thread.currentThread().toString()+":"+i);
}
}
public BThread() {
super();
// TODO Auto-generated constructor stub
}
public BThread(String name) {
super(name);
// TODO Auto-generated constructor stub
}
}
public class Test05 {
public static void main(String[] args) {
Tortoies tortoies = new Tortoies();
tortoies.setName("龟龟");
Rabbit rabbit = new Rabbit();
rabbit.setName("兔兔");
System.out.println("龟兔赛跑开始");
tortoies.start();
rabbit.start();
}
}
class Tortoies extends Thread {
@Override
public void run() {
for(int i = 1;i<=100;i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("乌龟跑了:"+i+"米");
}
System.out.println("乌龟到达了终点");
}
}
class Rabbit extends Thread {
@Override
public void run() {
for(int i = 1;i<=100;i+=3) {
try {
Thread.sleep((new Random().nextInt(7)+1)*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("兔子跑了:"+i+"米");
}
System.out.println("兔子到达了终点");
}
}
java
public class Test06 {
// join,一个线程加入到另一个线程中
public static void main(String[] args) {
DThread t = new DThread();
t.start();
System.out.println("主线程开始");
try {
// t加入到主线程中
// 让主线程无限制的去等待,等待子线程执行完毕
// t.join();//等价与t.join(0)
// t.join(0);
// 主线程只等待1000毫秒
t.join(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("主线程结束");
}
}
class DThread extends Thread {
@Override
public void run() {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("子线程执行完毕");
}
}