目录
1.创建线程的方式
1.1线程类
package com.qf.thread01;
public class Test01 {
/**
* 知识点:创建线程的方式1 -- 线程类
*/
//注意:main方法被主线程调用
public static void main(String[] args) {
//创建子线程的对象
MyThread t = new MyThread();
//启动线程(启动后,该线程被激活,才能去抢CPU资源)
t.start();
}
}
package com.qf.thread01;
//线程类
public class MyThread extends Thread{
//当前线程对象抢到CPU资源后,才会调用run方法
//run()方法:编写的是当前线程的功能
@Override
public void run() {
System.out.println("好好学习");
}
}
1.2任务类
package com.qf.thread02;
public class Test01 {
/**
* 知识点:创建线程的方式2 -- 任务类
*/
//Thread main = new Thread();
public static void main(String[] args) {
//创建任务类的对象
Task task = new Task();
//创建子线程对象
Thread t = new Thread(task);
//启动线程
t.start();
}
}
package com.qf.thread02;
//任务类
public class Task implements Runnable{
@Override
public void run() {
System.out.println("好好学习");
}
}
2.感受多线程之间争抢CPU资源的场景
package com.qf.thread03;
public class Test01 {
/**
* 知识点:感受多线程之间争抢CPU资源的场景
*
* 需求:编写一个多线程的应用程序,
* 主线程打印1-100之间的数字,
* 子线程打印200-300之间的数字,
* 观察其输出的结果,体会多线程互相争抢资源的场景
*/
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
for (int i = 1; i <= 100; i++) {
System.out.println("主线程:" + i);
}
}
}
package com.qf.thread03;
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 200; i <= 300; i++) {
System.out.println("子线程:" + i);
}
}
}
3.线程的优先级别
package com.qf.thread04;
public class Test01 {
/**
* 知识点:线程的优先级别
*
* 线程的优先级别:1~10,数字越大优先级越高
* 注意:优先级越高,线程抢到CPU资源的概率越大
*
* 需求:在主线程中创建两个以上的子线程,并且设置不同优先级,
* 观察其优先级对线程执行结果的”影响”。
*/
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
//设置优先级别
a.setPriority(Thread.MAX_PRIORITY);
b.setPriority(Thread.NORM_PRIORITY);
c.setPriority(Thread.MIN_PRIORITY);
a.start();
b.start();
c.start();
}
}
package com.qf.thread04;
public class A extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("A线程:" + i);
}
}
}
package com.qf.thread04;
public class B extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("B线程:" + i);
}
}
}
package com.qf.thread04;
public class C extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("C线程:" + i);
}
}
}
4.给线程取名字
方法一:
package com.qf.thread05;
public class Test01 {
/**
* 知识点:给线程取名字
*
* 需求:在主线程中创建两个以上的子线程,并且设置不同优先级,
* 观察其优先级对线程执行结果的”影响”。
*/
public static void main(String[] args) {
MyThread a = new MyThread("A");
MyThread b = new MyThread("B");
MyThread c = new MyThread("C");
//设置优先级别
a.setPriority(Thread.MAX_PRIORITY);
b.setPriority(Thread.NORM_PRIORITY);
c.setPriority(Thread.MIN_PRIORITY);
a.start();
b.start();
c.start();
}
}
package com.qf.thread05;
public class MyThread extends Thread{
private String threadName;//线程名
public MyThread(String threadName) {
this.threadName = threadName;
}
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(threadName + "线程:" + i);
}
}
}
方法二:
package com.qf.thread06;
public class Test01 {
/**
* 知识点:给线程取名字
*
* 需求:在主线程中创建两个以上的子线程,并且设置不同优先级,
* 观察其优先级对线程执行结果的”影响”。
*/
public static void main(String[] args) {
MyThread a = new MyThread("A");
MyThread b = new MyThread("B");
MyThread c = new MyThread("C");
//设置优先级别
a.setPriority(Thread.MAX_PRIORITY);
b.setPriority(Thread.NORM_PRIORITY);
c.setPriority(Thread.MIN_PRIORITY);
a.start();
b.start();
c.start();
}
}
package com.qf.thread06;
public class MyThread extends Thread{
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
//System.out.println(super.getName() + "线程:" + i);
//Thread类的静态方法,表示获取当前线程对象
Thread t = Thread.currentThread();
System.out.println(t.getName() + "线程:" + i);
}
}
}
5.线程的休眠
package com.qf.thread07;
import java.util.Random;
public class Test01 {
/**
* 知识点:线程的休眠
*
* 需求:编写一个抽取学员回答问题的程序,要求倒数三秒后输出被抽中的学员姓名
*/
public static void main(String[] args) throws InterruptedException {
String[] names = {"小偲","小灿","小鹏","小虹","小婷","小乐","小翔"};
Random random = new Random();
int index = random.nextInt(names.length);
for (int i = 3; i > 0; i--) {
System.out.println(i);
//让当前线程休眠(单位:毫秒)
Thread.sleep(1000);
}
System.out.println(names[index]);
}
}
6.线程的礼让
package com.qf.thread08;
public class Test01 {
/**
* 知识点:线程的礼让
*
* 需求:创建两个线程A,B,分别各打印100次,从1开始每次增加1,
* 其中B一个线程,每打印一次,就yield一次,观察实验结果
*/
public static void main(String[] args) {
A a = new A();
B b = new B();
a.start();
b.start();
}
}
package com.qf.thread08;
public class A extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("A线程:" + i);
}
}
}
package com.qf.thread08;
public class B extends Thread{
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println("B线程:" + i);
//礼让:让当前线程退出CPU资源,当前线程立刻进入到抢资源的状态(有可能又抢到了)
Thread.yield();
}
}
}
7.线程的合并
package com.qf.thread09;
public class Test01 {
/**
* 知识点:线程的合并
*
* 需求:主线程和子线程各打印200次,从1开始每次增加1,
* 当主线程打印到10之后,让子线程先打印完再打印主线程
*/
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
for (int i = 1; i <=200; i++) {
System.out.println("主线程:" + i);
if(i == 10){
//让线程t加入到主线程中,t线程执行完毕后,主线程再继续执行
t.join();
}
}
}
}
package com.qf.thread09;
public class MyThread extends Thread{
@Override
public void run() {
for (int i = 1; i <= 200; i++) {
System.out.println("子线程:" + i);
}
}
}
8.线程的中断
方法一:
package com.qf.thread10;
public class Test01 {
/**
* 知识点:线程的中断
*
* 怎么中断:run方法结束!!!
*/
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
Thread.sleep(3000);
//立即中断
t.stop();
}
}
package com.qf.thread10;
public class MyThread extends Thread{
@Override
public void run() {
while(true){
System.out.println("111");
System.out.println("222");
System.out.println("333");
System.out.println("444");
}
}
}
方法二:
package com.qf.thread11;
public class Test01 {
/**
* 知识点:线程的中断
*
* 怎么中断:run方法结束!!!
*/
public static void main(String[] args) throws InterruptedException {
MyThread t = new MyThread();
t.start();
Thread.sleep(3000);
//改变线程状态
t.interrupt();
}
}
package com.qf.thread11;
public class MyThread extends Thread{
@Override
public void run() {
//Thread.currentThread().isInterrupted() - 判断当前线程是否被销毁
//false-没有被销毁 true-被销毁
while(!Thread.currentThread().isInterrupted()){
System.out.println("111");
System.out.println("222");
System.out.println("333");
System.out.println("444");
}
}
}
9.守护线程/后台线程
package com.qf.thread12;
public class Test01 {
/**
* 知识点:守护线程/后台线程
* 理解:
* 我们创建的线程默认是前台线程
* 项目中所有的前台线程销毁后,守护线程也自动销毁
*
* 扩展:
* 1.垃圾回收器就是个后台线程
* 2.父类方法没有抛一般性异常,子类重写时就不会抛异常
*/
public static void main(String[] args) throws InterruptedException{
GuardThread guardThread = new GuardThread();
guardThread.setDaemon(true);//将当前线程设置成后台线程
guardThread.start();
for (int i = 1; i <=5; i++) {
System.out.println("主线程:" + i);
Thread.sleep(1000);
}
}
}
/**
* 重写:
* 应用场景:父类方法不满足子类对象时,在子类中重写即可
* 条件:
* 1.在子类中重写
* 2.返回值、方法名、参数列表
* 3.访问修饰符不能与父类更严格
* 4.父类没有抛异常,子类就不能抛异常
*/
class A{
public void method() throws InterruptedException{}
}
class B extends A{
@Override
public void method() throws InterruptedException{
}
}
package com.qf.thread12;
public class GuardThread extends Thread{
@Override
public void run() {
while(true){
System.out.println("后台线程正在默默守护着前台线程");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
}