多线程编程

继承Thread类
子类继承Thread类具备多线程能力
启动线程:子类对象.start()
不建议使用:避免OOP单继承局限性
实现Runnable接口
实现接口Runnable具有多线程能力
启动线程:传入目标对象+Thread对象.start()
推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用

线程是存在生命周期的。线程的生命周期分为5中不同的状态,由始至终分别是:
在这里插入图片描述
1、新建状态
处于新建状态中的线程对象,并不是一个独立的线程,无法运行,只有当被触发start方法时才会进入准备状态。新建状态是线程生命周期中的第一个状态,也是初始状态

2、准备状态
处于新建状态的线程对象,被调用了start方法,将进入准备状态;处于准备状态的线程随时都可能被系统选中进入运行状态,从而执行线程;可能同时有多个线程处于准备状态,然而究竟哪一个线程将进入运行状态,这是不确定的;
被阻塞的线程再次被唤醒时,并不会进入运行状态,而是进入准备状态,等待运行时机;

3、运行状态
处于准备状态中的线程一旦被系统选中,获得了运行时机,就会进入运行状态;在运行状态中,程序将执行线程类中run方法中的语句块;处于运行状态的线程,可以随时被设置为阻塞状态;
在单核CPU中,同一时刻只能有一个线程处于运行状态。在多核CPU中就可以多个线程同时处于运行状态,这也是多核CPU运行速度快的原因

4、等待(阻塞)状态
Java中提供了许多线程调度的方法,包括睡眠、阻塞、挂起和等待,使用这些方法都会将处于运行状态的线程调度到阻塞(等待)状态。处于阻塞状态的线程被解除后,并不会直接进入运行状态,而是进入准备状态,等待运行时机

5、死亡状态
当程序的run方法执行结束后,或程序发生异常终止运行后,线程会进入死亡状态。

6、如何创建线程对象?
1、继承Thread类
继承Thread类的子类具备了多线程的能力,重写Thread类的run方法,当线程被启动的时候,run方法中的程序就成为了一条独立的执行线程
2、实现Runnable接口
实现Runnable接口,需要实现Runnable接口中提供的run方法,当线程被启动的时候,run方法中的程序就成为了一条独立的执行线程

7、如何启动线程?
Java中对于线程后,可以保证的只是让每个线程都启动,并且会执行结果,但是无法决定多个线程中哪个先执行,哪个后执行

8、代码实例

package test1;
/**
*@author ShanHai:
*@version 创建时间:2021年8月24日 上午8:55:11
*/
public class MyThread extends Thread{
	private String name;//线程的名字
	
	 public  MyThread(String name){
		 this.name=name;
	 }

	@Override
	public void run() {//run方法中就是该线程要处理的功能
		for(int i=0;i<=100;i++){
			System.out.println(this.name+"===="+i);
		}
	}
	 
}

package test1;
/**
*@author ShanHai:
*@version 创建时间:2021年8月24日 上午8:59:58
*/
public class Test1 {
	public static void main(String[] args) {
		//1、实例化我的线程对象
		MyThread mt1=new MyThread("我的线程1");//定义一个线程
		MyThread mt2=new MyThread("我的线程2");
		MyThread mt3=new MyThread("我的线程3");
		MyThread mt4=new MyThread("我的线程4");
		//2、让线程进入准备状态
		mt1.start();
		mt2.start();
		mt3.start();
		mt4.start();
	}
}

9、如何控制(调度)线程?
1、睡眠的方法
当线程处于运行状态时,调用sleep方法将使线程从运行状态进入阻塞状态,从而使程序中断运行。该方法是使正在运行的线程让出CPU最简单的方法之一
2、让步的方法
Yield方法可以使当前正在运行的线程让出当前CPU,使线程由运行状态回到准备状态,让其他线程有进入运行状态的机会;然而将CPU让给哪一个线程是不确定的

10、代码实例

package test2;
/**
*@author ShanHai:
*@version 创建时间:2021年8月24日 上午9:11:59
*/
public class MyThread implements Runnable{
	private String name;

	public MyThread(String name) {
		super();
		this.name = name;
	}

	@Override
	public void run() {
		for(int i=0;i<=100;i++){
			System.out.println(this.name+"====="+i);
			if(i==30){
//				try {
//					Thread.sleep(3*1000);
//				} catch (InterruptedException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
				Thread.yield();
			}
		}
	}
	
}

package test2;
/**
*@author ShanHai:
*@version 创建时间:2021年8月24日 上午9:15:21
*/
public class Test {
	public static void main(String[] args) {
		//实例化MyThread对象
		MyThread mt1=new MyThread("我的线程1");
		MyThread mt2=new MyThread("我的线程2");
		MyThread mt3=new MyThread("我的线程3");
		//创建线程对象
		Thread t1=new Thread(mt1);
		Thread t2=new Thread(mt2);
		Thread t3=new Thread(mt3);
		//启动线程
		t1.start();
		t2.start();
		t3.start();
	
	}
}

Synchronized 和 Lock的区别

  1. Synchronized 内置的Java关键字,Lock是一个java类;
  2. Synchronized 无法判断获取锁的状态,Lock可以判断是否获取到了锁;
  3. Synchronized 会自动释放锁,Lock必须要手动释放锁!如果不释放锁,会死锁
  4. Synchronized 线程1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下去;
  5. Synchronized 可重入锁,不可以中断的,非公平;Lock,可重入锁,可以判断锁,非公平(可以自己设置);
  6. Aynchronized 适合锁少量的代码同步问题,Lock适合锁大量的同步代码!
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShanHai山海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值