21-多线程(一),线程创建,线程的状态

21-多线程(一),线程创建,线程的状态

  • 多线程概念:

    • 程序: 是一个指令的集合(静态)
    • 线程: 正在执行中的程序
      1. 线程是程序的一次静态执行的过程,占用特定的地址空间
      2. 每个线程都是独立的
    • 进程: 一个进程可以拥有多个并行的线程

    线程的创建:

    ​ 两种:

      1.	继承thread类
      2.	实现Runnable接口
    
//1.继承thread类
public class Mythread extends Thread{		//具有了多线程的功能
	@Override
	public void run() {		//重写,线程操作的代码
		//run方法中的代码称之为线程体,(线程所有执行和的主题)
		for(int i=0;i<10;i++) {
			System.out.println(Thread.currentThread().getName()+"==="+i);
		}
	}
	//构造方法
	public Mythread(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}
	public Mythread() {
		super();
		// TODO Auto-generated constructor stub
	}
}
import java.util.Scanner;

public class Test {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		System.out.println("请输入你的年龄: ");		
		//int age = input.nextInt();	//等待控制台输入年龄
		
		//创建线程
		Mythread my = new Mythread();		//创建一个线程对象
		Mythread my1 = new Mythread();
		Mythread my2 = new Mythread();
		
		//my.run();		//对象点方法名
		my1.start();		//启动一个线程
		int age1 = input.nextInt();
		my2.start();		//不可以重复调用
		
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName()+"===="+i);
		}
		//创建带有参数的线程对象
		Mythread myy = new Mythread("线程一");
		myy.start();
	}
}
  • 2.实现Runnable接口的类具有多线程的能力

    建议使用接口的方式:

    ​ 优点: 1. 可以避免java中类的单继承所带来的局限性

    ​ 2.可以实现资源的共享

package deskdemo.demo2;

public class MyRun implements Runnable{

	@Override
	public void run() {		//实现接口当中的方法,实现多线程的
		// TODO Auto-generated method stub
		for (int i = 0; i < 5; i++) {
			System.out.println(Thread.currentThread().getName()+"===="+i);
		}
	}
	
}

public class Test {
	public static void main(String[] args) {
		MyRun mr = new MyRun();
		Thread t = new Thread(mr);		//调用带参构造方法创建对象,参数是Runnable接口的实例
		Thread t1 = new Thread(mr);
		Thread t2 = new Thread(mr);
		t.start();
		t1.start();
		t2.start();
	}
}
  • 多线程案例

    有5张票,100个人在排队买票,分三个窗口都在排队买票,看下’继承Thread类的实现方式和实现Runnable接口的区别.

//继承Thread类的方式
public class MyTicket extends Thread{
	private int ticket = 5;		//有5张票
	//重写run方法
	public void run() {
		for (int i = 0; i < 5; i++) {		//有100个人在排队买这五张票
			if(ticket>0) {
				System.out.println(Thread.currentThread().getName()+"买票"+i);
			}
		}
	}
}

public class Test {
	public static void main(String[] args) {
		//创建三个窗口买票,每个窗口都是100人
		MyTicket m1 = new MyTicket();
		MyTicket m2 = new MyTicket();
		MyTicket m3 = new MyTicket();
		
		m1.start();
		m2.start();
		m3.start();
	}
}
//实现Runnable接口的方式
public class MyRun implements Runnable{
	private int ticket = 5;		//有5张票
	//重写run方法
	public void run() {
		for (int i = 0; i < 5; i++) {		//有100个人在排队买这五张票
			if(ticket>0) {
				System.out.println(Thread.currentThread().getName()+"买票"+i);
			}
		}
	}
}

public class TestRun {
	public static void main(String[] args) {
		//三个窗口共享5张票,创建线程类的对象
		MyRun mr = new MyRun();//创建一个线程类的对象,在堆中开辟一块空间,有一个属性ticket,值为5
		//借助thread类去启动线程
		Thread t1 = new Thread(mr);
		Thread t2 = new Thread(mr);
		Thread t3 = new Thread(mr);
		t1.start();
		t2.start();
		t3.start();
		
	}
}
  • 线程的状态:
    1. 新生状态:
      1. 使用new关键字建立一个线程后,该线程就处于新生状态.
      2. 处于新生状态的线程有自己的内存空间,通过调用start()方法进入就绪状态.
    2. 就绪状态:
      1. 处于就绪状态的线程具备了运行的条件,但还没有分配到cpu,处于线程的就绪队列,等到 系统为其分配CPU资源
      2. 当系统选定一个等待执行的线程后,它就会从就绪状态进入到执行状态,该动作称之为CPU调度
    3. 运行状态:
      1. 在运行状态的线程执行自己的run方法中的代码,直到等到都资源而阻塞或者完成而死亡
      2. 如果在给定的时间片内没有执行结束,就会被系统给换下来回到等待执行状态
    4. 阻塞状态:
      1. 处于运行状态的线程在某些情况下,如执行了sleep方法后,等待I/O设备等资源,将让出CPU时停止自己的运行,进入阻塞状态
      2. 在阻塞状态的线程布恩那个进入就绪队列,只有当阻塞的原因消除后,如睡眠时间到了,或者I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来的停止的位置开始继续执行
    5. 死亡状态:
      1. 死亡状态是线程声明周期中的最后一个阶段,线程的死亡的原因有三个,一个是正常的线程完成了它所有的工作;另一个是线程被强制型的终止,如通过stop方法来终止一个线程(不推荐使用);三是线程抛出未捕获的异常.

猜你喜欢

转载自blog.csdn.net/qq_26270869/article/details/90174423