admin 2026-08-08 03:45:39 加拿大女足世界杯

线程的状态和生命周期

线程概念

每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工作,称为多线程。一个进程可以产生多个线程,多线程机制使程序运行效率变得更高。进程是指在系统中正在运行的一个应用程序,线程是比进程更小的执行单位

线程的实现方式

测试全班IP是否通,来演示多线程的好处,示例:

代码语言:javascript复制public class PingIPDemo {

/**

* pingIp的方法

* @param ipAddr

/

public static void pingIp(String ipAddr){

try {

//Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接,执行命令,把结果放入Process中

Process process = Runtime.getRuntime().exec("ping "+ipAddr);

//使用BufferedReader里面的readLine()方法获取运行时信息

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

String line=null;

//循环读取结果

while((line=bufferedReader.readLine())!=null){

System.out.println(line);

//如果包含TTL说明ping通

if(line.contains(“TTL”)){

System.out.println(“ping tong”);

return;

}

}

System.out.println(“bu tong”);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

public static void main(String[] args) {

//循环测试班级IP是否通

for(int i=1;i<=3;i++){

pingIp(“192.168.1.”+i);

}

}

}

继承thread类实现多线程

代码语言:javascript复制public class PingIPExtendThread extends Thread {

private String ip;

/*

* 带参构造

* @param ip

*/

public PingIPExtendThread(String ip){

this.ip=ip;

}

@Override

public void run() {

// TODO Auto-generated method stub

PingIPDemo.pingIp(ip);

}

}public class TestPingIP {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

for(int i=1;i<=3;i++){

//继承Thread后

PingIPExtendThread pingIPExtendThread=new PingIPExtendThread("192.168.1."+i);

//启动线程

pingIPExtendThread.start();

}

}}

实现Runnable接口演示多线程

代码语言:javascript复制public class PingIPImplementsRunnable implements Runnable {

private String ip;

public PingIPImplementsRunnable(String ip) {

this.ip=ip;

}

@Override

public void run() {

// TODO Auto-generated method stub

PingIPDemo.pingIp(ip);

}}

public class TestPingIP {

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

/*for(int i=1;i<=3;i++){

//继承Thread后

PingIPExtendThread pingIPExtendThread=new PingIPExtendThread("192.168.1."+i);

//启动线程

pingIPExtendThread.start();

}*/

for(int i=1;i<=3;i++){

//继承Thread后

PingIPImplementsRunnable pingIPImplementsRunnable=new PingIPImplementsRunnable("192.168.1."+i);

//启动线程

new Thread(pingIPImplementsRunnable).start();

}

}}继承thread类和实现runnable接口有什么区别

模拟卖票系统演示区别:继承Thread类受单继承影响,不适合多个线程共享资源

代码语言:javascript复制/**

*@className:SaleTicketExtendThread.java

*@discription:

*@createTime:2025-7-8下午5:10:40

*@author:zz

*/

public class SaleTicketExtendThread extends Thread {}

实现runnable,主要测试方法不同,实现接口,启动线程时可以两个

代码语言:javascript复制/**

*@className:SaleTicketImplementsRunnable.java

*@discription:

*@createTime:2025-7-8下午5:18:41

*@author:zz

*/

public class SaleTicketImplementsRunnable implements Runnable {private int ticket=5;

Object o=new Object();

@Override

public void run() {

// TODO Auto-generated method stub

while(ticket>0){

System.out.println(Thread.currentThread().getName()+"卖票,剩余"+ticket--+"张!");

}

}

public static void main(String[] args) {

SaleTicketImplementsRunnable saleTicketImplementsRunnable =new SaleTicketImplementsRunnable();

new Thread(saleTicketImplementsRunnable,"张三").start();

new Thread(saleTicketImplementsRunnable,"李四").start();

}}

线程的状态

五种状态:

新建(程序还没有开始运行线程中的代码)

就绪(当start()方法返回后,线程就处于就绪状态,处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间)

运行(线程获得CPU时间后,它才进入运行状态,真正开始执行run())

阻塞(等待wait、带超时的等待sleep)

终止(死亡,正常退出或者异常终止)

s(1) 匿名线程类

代码语言:javascript复制/**

• @className:AnonymousInternalClass.java

• @discription:

• @createTime:2025-7-8下午10:31:44

• @author:zz

*/

public class AnonymousInternalClass {

public static void main(String[] args) {

// 匿名内部类1

new Thread() {

public void run() {

System.out.println(“我没有名称!!!”);

}

}.start();

// 匿名内部类2

new Thread(new Runnable() {

public void run() {

System.out.println(“我也没有名称!!!”);

}

}).start();

}

}(2) Sleep和wait的区别

讲区别之前,需要先讲解同步锁

synchronized 可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。修改卖票代码,让方法同步,保证卖票不错!

代码语言:javascript复制/**

*@className:SaleTicketImplementsRunnable.java

*@discription:

*@createTime:2025-7-8下午5:18:41

*@author:zz

*/

public class SaleTicketImplementsRunnable implements Runnable {private int ticket=5;

@Override

public void run() {

// TODO Auto-generated method stub

while(ticket>0){

synchronized (this) {

System.out.println(Thread.currentThread().getName()+"卖票,剩余"+ticket--+"张!");

}

}

}

public static void main(String[] args) {

SaleTicketImplementsRunnable saleTicketImplementsRunnable =new SaleTicketImplementsRunnable();

new Thread(saleTicketImplementsRunnable,"张三").start();

new Thread(saleTicketImplementsRunnable,"李四").start();

}}

1,Sleep方法是在Thread类里面,wait在Object类里面

2,Sleep方法可以不在同步块里面运行,wait不行

3,Wait方法阻塞时,需要唤醒notify操作,释放了锁

4,Sleep放阻塞时,不放锁,wait 方法释放锁,只有当其他线程调用notify方法时,重新获取锁

代码语言:javascript复制package com.2025.multithread.demo;

/**

*@className:ThreadStatusDemo.java

*@discription:

*@author:zhz

*@createTime:2025-3-28下午3:56:59

@version:1.0.0

/

public class ThreadStatusDemo {

static Object o = new Object();

static Object o1 = new Object();

static Runnable runnable1 =new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized (o) {//首先不加同步锁,讲解sleep用法

System.out.println(“qy76开班”);

try {

//sleep就是正在执行的线程主动让出cpu,cpu去执行其他线程,在sleep指定的时间过后,cpu才会回到这个线程上继续往下执行

Thread.sleep(10000);

//如果在非同步控制方法里调用notify wait方法,程序能通过编译,但运行的时候,将得到IllegalMonitorStateException异常

//wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法

//notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁

o.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(“qy76毕业”);

}

}

};

static Runnable runnable2 =new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized (o) {

System.out.println(“qy80开班”);

try {

Thread.sleep(1000);

o.notify();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(“qy80毕业”);

}

}

};

/

* @param args

/

public static void main(String[] args) {

// TODO Auto-generated method stub

new Thread(runnable1).start();

new Thread(runnable2).start();

}

}

(3) 同步块(保证线程正在运行的代码不被其他线程运行)

代码语言:javascript复制package com.2025.multithread.demo;

/

*@className:ThreadStatusDemo.java

*@discription:

*@author:zhz

*@createTime:2025-3-28下午3:56:59

@version:1.0.0

/

public class ThreadStatusDemo {

static Object o = new Object();

static Object o1 = new Object();

static Runnable runnable1 =new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized (o) {

System.out.println(“qy76开班”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(“qy76毕业”);

}

}

};

static Runnable runnable2 =new Runnable() {

@Override

public void run() {

// TODO Auto-generated method stub

synchronized (o) {

System.out.println(“qy80开班”);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(“qy80毕业”);

}

}

};

/

* @param args

/

public static void main(String[] args) {

// TODO Auto-generated method stub

new Thread(runnable1).start();

new Thread(runnable2).start();

}

}

线程的死锁

线程死锁原理:一个线程拥有A锁想得到B锁,另一个线程拥有B锁想得到A锁

使用父亲和儿子的例子演示死锁

代码语言:javascript复制/

*@className:Father.java

*@discription:

*@createTime:2025-7-8下午5:57:37

*@author:zz

*/

public class Father {/**

* 说

*/

public void say(){

System.out.println("给我成绩单,我就给你买玩具!");

}

/**

* 得到玩具

*/

public void get(){

System.out.println("得到成绩单!");

}}

/**

*@className:Chirdren.java

@discription:

@createTime:2025-7-8下午5:59:12

@author:zz

/

public class Chirdren {

/

* 说

/

public void say(){

System.out.println(“给我玩具,我就给你成绩单!”);

}

/

* 得到

/

public void get(){

System.out.println(“得到玩具!”);

}

}

package com.2025.multithread.demo;

/

*@className:DeadLockDemo.java

*@discription:

*@author:zhz

*@createTime:2025-3-28下午4:38:41

*@version:1.0.0

**/

public class DeadLockDemo implements Runnable {

static Father father =new Father();

static Chirdren chirdren =new Chirdren();

private boolean isFather=true;

@Override

public void run() {

// TODO Auto-generated method stub

if(isFather){

//拥有父亲锁

synchronized (father) {

father.say();

try {

//睡觉

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//睡醒后要孩子锁,但是没有丢掉父亲锁

synchronized (chirdren) {

father.get();

}

}

}else{

//拥有孩子锁

synchronized (chirdren) {

chirdren.say();

try {

//睡觉

Thread.sleep(200);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

//睡醒后向要父亲锁,单是没有丢掉孩子锁

synchronized (father){

chirdren.get();

}

}

}

}

public static void main(String[] args) {

DeadLockDemo deadLockDemo1 = new DeadLockDemo();

deadLockDemo1.isFather=true;

DeadLockDemo deadLockDemo2 = new DeadLockDemo();

deadLockDemo2.isFather=false;

new Thread(DeadLockDemo1).start();

new Thread(DeadLockDemo2).start();

}

}