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("子线程执行完毕");
	}
}
相关推荐
江-小北2 分钟前
Java基础面试题04:Iterator 和 ListIterator 的区别是什么?
java·开发语言
wmd131643067125 分钟前
IDEA插件CamelCase,快速转变命名格式
java·ide·intellij-idea
明明真系叻28 分钟前
第二十二周机器学习笔记:动手深度学习之——线性代数
笔记·深度学习·线性代数·机器学习·1024程序员节
大筒木老辈子33 分钟前
Linux笔记---进程:初识进程
linux·服务器·笔记
捂月39 分钟前
Spring Boot 核心逻辑与工作原理详解
java·spring boot·后端
埋头编程~42 分钟前
【C++】踏上C++学习之旅(十):深入“类和对象“世界,掌握编程黄金法则(五)(最终篇,内含初始化列表、静态成员、友元以及内部类等等)
java·c++·学习
菜鸟起航ing1 小时前
Java中日志采集框架-JUL、Slf4j、Log4j、Logstash
java·开发语言·log4j·logback
2401_879103681 小时前
24.11.23 Ajax
笔记·ajax
Nightselfhurt1 小时前
RPC学习
java·spring boot·后端·spring·rpc
苹果醋31 小时前
vue3 在哪些方便做了性能提升?
java·运维·spring boot·mysql·nginx