java多线程入门(主线程、线程组、线程优先级、精灵线程/守护线程)

java多线程入门

源码点这里

接下来,我们讲一讲主线程、线程组、线程优先级、精灵线程/守护线程

在讲之前,我们先简要的说一说,什么是线程,进程,程序

等一下,我们直接po代码和截图,直接看具体的案例

多线程即在同一时间,可以做多件事情(说白了,就是齐头并进)

单线程就是按部就班

程序:一系列命令/指令的集合,说白了,就是一堆英文字母和数字组成的指令,这堆英文字母和数字需要符合编程语言的语法规则!(程序是静态的,也就是说,程序员编写好了一个程序,那个程序就静静的、安静的躺在电脑磁盘上,那就是程序)

进程:可以理解成动态的程序,说白了,就是把安静的躺在电脑磁盘上的程序打开运行,程序一打开运行,就会在电脑的内存中运行,占用电脑内存资源,占用cpu资源,这就是一个进程,简而言之,就是已经在内存中运行的程序就是进程

线程:线程就是进程/程序中的相对独立的代码段,比进程更小的运行单位,多个线程构成一个进程,线程是依附于进程的。

进程是由操作系统来调度的!

线程是由进程来调度的,线程是依附于进程的!

创建多线程有2种方式,分别是继承线程Thread类,实现Runnable接口

注意:

1.继承Thread类的线程类不能再继承其他类了(因为在Java中,一个类不能同时继承多个类,java是单继承的

2.我们在java中创建线程,建议使用实现Runnable接口的方式,好处就是避免了单继承的局限性。比如当一个student类继承了person类,再需继承其他的类时就不能了,所以在定义线程时,建议使用实现Runnable接口的方式,因为对系统的侵入性比较小!(在java中,一个类可以实现多个接口)

接下来,直接po代码和截图

案例不算太难,代码量也不多,希望大家耐心看完,以张无忌、赵敏、周芷若为案例

Zhangwuji类

package com.demo.thread;

/** 
 * 张无忌类
 */
public class Zhangwuji {
	
	public void zhui() {
		for (int i = 0; i < 5; i++) {
		System.out.println("张无忌追啊追----");
		}
	}

}

Zhangwuji2类

package com.demo.thread;

/** 
 * 方式1,继承Thread类,这种方式对系统的侵入性更大,如
 * 果本类下面还有子类,那么就等于本类的子类也继承了Thread类的多线程机制,所
 * 以继承Thread类这种方式对系统的侵入性更大
 * (在java中,是单继承的,但是java中的一个类可以实现多个接口)
 * 本类继承Thread类后,就不能再继承其他类了,所以,继承Thread类这种方式,扩展性不太好,所
 * 以建议使用实现Runnable接口这种方式
 * 张无忌类
 */
public class Zhangwuji2 extends Thread{
	
	//线程体
	@Override
	public void run() {
		zhui();
	}
	
	public void zhui() {
		for (int i = 0; i < 5; i++) {
		System.out.println("张无忌追啊追----");
		}
	}

}

Zhangwuji3类

package com.demo.thread;

/** 
 * 方式2,实现Runnable接口,这种方式对系统的侵入性更小,而且本
 * 类还可以实现其他的接口和继承其他的类,扩展性更好(在java中,是单继承的,但
 * 是java中的一个类可以实现多个接口)
 * 张无忌类
 */
public class Zhangwuji3 implements Runnable{
	
	//线程体
	@Override
	public void run() {
		zhui();
	}
	
	public void zhui() {
		for (int i = 0; i < 5; i++) {
		System.out.println("张无忌追啊追----");
		}
	}

}

Zhangwuji4类

package com.demo.thread;

/** 
 * 方式2,实现Runnable接口,这种方式对系统的侵入性更小,而且本
 * 类还可以实现其他的接口和继承其他的类,扩展性更好(在java中,是单继承的,但
 * 是java中的一个类可以实现多个接口)
 * 张无忌类
 */
public class Zhangwuji4 implements Runnable{
	
	//线程体
	@Override
	public void run() {
		zhui();
	}
	
	public void zhui() {
		for (int i = 0; i < 5; i++) {
		System.out.println("我是张无忌,我追啊追!!!!!!!!");
		}
	}

}

Zhaomin类

package com.demo.thread;

/** 
 * 赵敏类 
 */
public class Zhaomin {
	
	public void quan() {
		for (int i = 0; i < 5; i++) {
		System.out.println("赵敏劝啊劝!!!!");
		}
	}

}

Zhaomin2类

package com.demo.thread;

/** 
 * 赵敏类 
 */
public class Zhaomin2 extends Thread{
	
	//线程体
	@Override
	public void run() {
		quan();
	}
	
	public void quan() {
		for (int i = 0; i < 5; i++) {
		System.out.println("赵敏劝啊劝!!!!");
		}
	}

}

Zhouzhiruo类

package com.demo.thread;

/** 
 * 周芷若类
 */
public class Zhouzhiruo {
	
	public void pao() {
		for (int i = 0; i < 5; i++) {
			System.out.println("周芷若生气气了,跑啊跑....");
		}
	}

}

Zhouzhiruo2类

package com.demo.thread;

/** 
 * 周芷若类
 */
public class Zhouzhiruo2 extends Thread{
	
	
	//线程体
	@Override
	public void run() {
		pao();
	}

	public void pao() {
		for (int i = 0; i < 5; i++) {
			System.out.println("周芷若生气气了,跑啊跑....");
		}
	}

}

UsualThread类

这是一个普通的用户线程,UsualThread类(ps:我们可以把守护线程以外的线程,都可以叫做是用户线程)

package com.demo.thread;

//这是一个普通的用户线程
public class UsualThread extends Thread {

	@Override
	public void run() {
		int a = 0;
		while (true) {
			System.out.println("我是一个普通的用户线程" + a++);
		}
	}

}

WaterSupplyThread类

周芷若和张无忌和赵敏,他们肯定也会口渴,肯定是要喝水的,我这里写了一个供水线程

供水线程,WaterSupplyThread类

package com.demo.thread;

//这是一个供水线程(是一个精灵线程,精灵线程又叫做守护线程)
public class WaterSupplyThread extends Thread {

	@Override
	public void run() {
		int i = 0;
		while (true) {
			System.out.println("我是一个供水的守护线程" + i++);
		}
	}

}

Test类

package com.demo.thread;

public class Test {

	/** 
	* 没使用线程
	*/
	public static void main(String[] args) {
		//如下这种方式就是单线程的方式(单线程就是我们所说的按部就班)
		Zhouzhiruo zhouzhiruo = new Zhouzhiruo();
		Zhangwuji zhangwuji = new Zhangwuji();
		Zhaomin zhaomin = new Zhaomin();
		zhouzhiruo.pao();
		zhangwuji.zhui();
		zhaomin.quan();
	}

}

运行结果:

Test2类

package com.demo.thread;

public class Test2 {

	/** 
	* 使用了线程
	*/
	public static void main(String[] args) {
		//如下这种方式就是多线程的方式(多线程就是我们所说的齐头并进)
		Zhouzhiruo2 zhouzhiruo2 = new Zhouzhiruo2();
		Zhangwuji2 zhangwuji2 = new Zhangwuji2();
		Zhaomin2 zhaomin2 = new Zhaomin2();
		zhouzhiruo2.start();
		zhangwuji2.start();
		zhaomin2.start();
	}

}

运行结果:可以多执行几次,每次运行的结果可能不一样

Test3类

package com.demo.thread;

public class Test3 {

	/** 
	* 使用了线程
	*/
	public static void main(String[] args) {
		//如下这种方式就是多线程的方式(多线程就是我们所说的齐头并进)
		Zhouzhiruo2 zhouzhiruo2 = new Zhouzhiruo2();
		Zhangwuji3 zhangwuji3 = new Zhangwuji3();
		Zhaomin2 zhaomin2 = new Zhaomin2();
		
		//构造方法传参
		Thread cpu = new Thread(zhangwuji3);
		
		zhouzhiruo2.start();
		cpu.start();
		zhaomin2.start();
	}

}

运行结果:可以多执行几次,每次运行的结果可能不一样

接下来,讲主线程线程优先级

主线程线程优先级

TestMainThread类

package com.demo.thread;

public class TestMainThread {

	public static void main(String[] args) {
		/**
		 * 在java程序启动时,有一个线程立即执行,我们把该线程称为程序的主线程
		 * 主线程的重要性体现在两方面
		 * 1.它是产生其他子线程的线程
		 * 2.通常它必须最后完成执行,因为它执行各种关闭动作
		 * 
		 */
		//当前正在运行的线程对象
		//主线程
		Thread currentThread = Thread.currentThread();//Thread类的静态方法
		System.out.println(currentThread + "当前线程的名称=" +currentThread.getName());
		//我们可以给线程设置名称
		currentThread.setName("jiangxi");
		System.out.println(currentThread + "当前线程的名称=" +currentThread.getName());
		
		//如下这种方式就是多线程的方式(多线程就是我们所说的齐头并进),线程有优先级的概念,线程的优先级默认为5
		Zhouzhiruo2 zhouzhiruo2 = new Zhouzhiruo2();
		Zhangwuji3 zhangwuji3 = new Zhangwuji3();
		Zhaomin2 zhaomin2 = new Zhaomin2();
		
		//构造方法传参
		Thread cpu = new Thread(zhangwuji3);//构造器传参
		System.out.println("线程名字=" + cpu.getName() + "******");
		System.out.println("线程信息=" + cpu.currentThread().getName() + "-----");
		System.out.println("线程信息=" + cpu.currentThread() + "######");
		
		// 构造函数传参
//		cpu = new Thread(new Zhangwuji4());// 构造器传参
//		System.out.println("线程名字=" + cpu.getName() + "******");
//		System.out.println("线程信息=" + cpu.currentThread().getName() + "-----");
//		System.out.println("线程信息=" + cpu.currentThread() + "######");
		
		/*
		 * 注意:
		 * java线程的优先级并不代表一定会执行,只是说明执行的概率高一些,所以在java中用优
		 * 先级控制执行顺序是不确定的
		 */
		
		//设置优先级,优先级设置成10,优先级最高,属于抢占式策略。(而优先级相同的线程,采用时间片式策略)
		//要在调用start()方法前设置优先级,优先级越高,就能获得更多的cpu资源
		zhaomin2.setPriority(Thread.MAX_PRIORITY);
		System.out.println("赵敏的优先级=" + zhaomin2.getPriority());
		//线程的优先级默认为5
		System.out.println("周芷若的优先级=" + zhouzhiruo2.getPriority());
		
		//调用start()方法启动线程
		zhouzhiruo2.start();
		cpu.start();
		zhaomin2.start();
		
		//垃圾回收车是一个守护线程(守护线程又叫做精灵线程),垃圾回收车线程的优先级最低,为1级
		System.gc();//该行代码的意思是,建议垃圾回收车线程去运行,但是到底会不会运行,这是不一定的
		
		String activeCount = "当前线程组里面,正在活动的线程的数目=";
		//当前线程组里面,正在活动的线程的数目
		//Thread类的静态方法
		System.out.println(activeCount + Thread.activeCount());
		
	}

}

运行结果:可以多执行几次,每次运行的结果可能不一样

接下来,讲线程组

线程组

TestThreadGroup类

package com.demo.thread;

public class TestThreadGroup {

	public static void main(String[] args) {
		//创建一个线程组,它默认隶属于系统线程组
		ThreadGroup jerryThreadGroup = new ThreadGroup("jerryThreadGroup");
		System.out.println("####################线程组名字=" + jerryThreadGroup.getName());
		System.out.println("###########当前线程组的父线程组名字=" + jerryThreadGroup.getParent().getName());
		
		Zhouzhiruo2 zhouzhiruo2 = new Zhouzhiruo2();
		Zhangwuji3 zhangwuji3 = new Zhangwuji3();
		Zhaomin2 zhaomin2 = new Zhaomin2();
		
		//构造方法传参
		Thread cpu = new Thread(jerryThreadGroup, zhangwuji3);//构造器传参
		
		//调用start()方法启动线程
		zhouzhiruo2.start();
		cpu.start();
		zhaomin2.start();
		
		
		String activeCount = " 当前线程组里面,正在活动的线程和线程组的数目=";
		//当前线程组里面,正在活动的线程的数目
		System.out.println("线程组名字=" + jerryThreadGroup.getName() + activeCount + jerryThreadGroup.activeCount());
		//通过getThreadGroup()函数得到当前线程隶属的线程组
		ThreadGroup threadGroup = zhouzhiruo2.getThreadGroup();
		//线程组的activeCount()函数得到当前线程组中活动的线程和线程组数目
		System.out.println("线程组名字=" + threadGroup.getName() + activeCount + threadGroup.activeCount());

	}

}

运行结果:可以多执行几次,每次运行的结果可能不一样

运行结果,情况1

运行结果,情况2

接下来,讲守护线程(守护线程又叫做精灵线程)

守护线程/精灵线程

TestDaemonThread类

我们可以把守护线程以外的线程,都可以叫做是用户线程

把供水线程设置为守护线程(只要没有用户线程在运行了,那守护线程就会停止,也不会再继续运行了)

package com.demo.thread;

// 测试守护线程(守护线程又叫精灵线程)
public class TestDaemonThread {

	public static void main(String[] args) {
		Zhouzhiruo2 zhouzhiruo2 = new Zhouzhiruo2();
		Zhangwuji3 zhangwuji3 = new Zhangwuji3();
		Zhaomin2 zhaomin2 = new Zhaomin2();

		// 构造方法传参
		Thread cpu = new Thread(zhangwuji3);
		
		WaterSupplyThread waterSupplyThread = new WaterSupplyThread();

		//垃圾回收车是一个守护线程(守护线程又叫做精灵线程),垃圾回收车线程的优先级最低,为1级
		//把供水线程设置为守护线程(只要没有用户线程在运行了,那守护线程就会停止,也不会再继续运行了)
		waterSupplyThread.setDaemon(true);
		waterSupplyThread.start();
		
		zhouzhiruo2.start();
		cpu.start();
		zhaomin2.start();
		
	}
	

}

运行结果:

只要没有用户线程在运行了,那守护线程就会停止,也不会再继续运行了

TestDaemonThread2类

把供水线程设置为守护线程(只要还有用户线程在运行,那守护线程就不会停止,也在继续运行)

package com.demo.thread;

// 测试守护线程(守护线程又叫精灵线程)
public class TestDaemonThread2 {

	public static void main(String[] args) {
		Zhouzhiruo2 zhouzhiruo2 = new Zhouzhiruo2();
		Zhangwuji3 zhangwuji3 = new Zhangwuji3();
		Zhaomin2 zhaomin2 = new Zhaomin2();
		UsualThread usualThread = new UsualThread();

		// 构造方法传参
		Thread cpu = new Thread(zhangwuji3);
		
		WaterSupplyThread waterSupplyThread = new WaterSupplyThread();

		//垃圾回收车是一个守护线程(守护线程又叫做精灵线程),垃圾回收车线程的优先级最低,为1级
		//把供水线程设置为守护线程(只要还有用户线程在运行,那守护线程就不会停止,也在继续运行)
		waterSupplyThread.setDaemon(true);
		waterSupplyThread.start();
		
		zhouzhiruo2.start();
		cpu.start();
		zhaomin2.start();
		usualThread.start();
		
	}

}

运行结果:

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值