多线程>>>>>1

本文深入解析程序、进程及线程的概念,阐述它们之间的区别与联系,介绍线程的创建方式及其在Java中的应用,包括如何通过Thread类和Runnable接口创建线程,以及线程的生命周期和线程间的数据共享。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序,进程和线程

程序:一个可执行的文件

进程:一个正在运行的程序,也可以理解成在内存中开辟了一块儿空间

线程:负责程序的运行,可以看做一条执行的通道或执行单元,所以我们通常将进程的工作理解成线程的工作

进程中必须有线程,至少有一个。

单线程:当有一个线程的时候我们称为单线程(唯一的线程就是主线程)。

多线程:当有一个以上的线程同时存在的时候我们称为多线程。

多线程的作用:为了实现同一时间干多件事情(宏观上)。不能提高效率

任务区:我们将线程工作的地方称为任务区。每一个线程都有一个任务区,任务区通过对应的方法产生作用。

Java或者说JVM默认是多线程的,且至少要有两个线程:

主线程:任务区:main函数

垃圾回收线程:任务区:finalize函数

public class Demo {
	public static void main(String[] args) {//有一个线程----主线程

		new MyTest();//匿名对象---垃圾
		
		/*
		  手动运行gc:垃圾回收器,运行垃圾回收机制
		  原理:当执行gc方法时,会触发垃圾回收机制,
                  开启垃圾回收线程,自动调用finalize方法
		  注意点:多个线程之间是抢cpu的关系,cpu有随机性.
	        */
		System.gc();//有两个线程,主线程和垃圾回收线程
		
		System.out.println("main");
	}//主函数结束,主任务区结束,线程随着任务的结束而结束,随着任务的开始而开始.
         //当线程还在工作的时候,进程不能结束.
}

class MyTest{
	//重写finlize方法
	/*
	正常情况下,这个函数是由系统调用的.重写它是为了观察多线程的实现
	正常情况下,当MyTest的对象被释放的时候,会自动调用他的finalize方法
	 */
	protected void finalize() throws Throwable {
         System.out.println("finalize");
	}
}

Thread和Runnable

默认情况下,主线程和垃圾回收线程都是由系统创建的,但是我们需要完成自己的功能时就要创建自己的线程对象

Java将线程面向对象了,形成的类就是Thread,在Thread类内部执行任务的方法叫run()

注意:如果想让run作为任务区,必须让他去被自动调用。我们通过执行start()方法,来实现run方法的调用。否则就会作为所在线程的一个函数出现。

创建线程的三种情况:

First:

public class Demo {
	public static void main(String[] args) {//两个,垃圾回收线程和主线程,但是一般先将垃圾回收线程忽略掉
		//通过Thread类直接创建线程
		Thread thread1 = new Thread();//创建了一个线程
		Thread thread2 = new Thread();//创建了一个线程
		//调用start(),开启线程
		thread1.start();//两个
		thread2.start();//三个
		
		System.out.println("main");
	}
}

Second:

public class Demo8 {
	public static void main(String[] args) {
		
                //通过Thread类的子类创建线程
		MyThread thread1 = new MyThread("tan jie");//创建了一个线程     thread-0
		MyThread thread2 = new MyThread("yi fei");//创建了一个线程     thread-1
		//调用start(),开启线程
		thread1.start();
		thread2.start();
		
		//主线程的系统名字是main
		for(int i=0;i<10;i++){
			System.out.println(Thread.currentThread().getName()+"    main    i:"+i);
		}
		
		//手动调用run方法,他只是一个普通的方法,不能代表任务区,只有被自动调用的时候才是任务区
		//手动调用时,调用run方法处的线程,就是run方法内部对应的线程.
		thread1.run();
		
	}
}

//写Thread类的子类,因为Thread类的run方法是空的,无法实现具体的任务,所以要通过创建子类的方式实现我们自己的功能
//作为Thread的子类也是线程类
class MyThread extends Thread{
	String myname;
	public MyThread(String myname) {
		super();
		this.myname = myname;
	}
	/*
	 *重写run()方法,---作为线程的任务区,完成我们的功能.
	 *Thread.currentThread():获取的是当前的任务区对应的线程
	 *getName():线程的名字
	 */
	public void run() {
		for(int i=0;i<10;i++){
			System.out.println(Thread.currentThread().getName()+"    run:"+myname+"   i:"+i);
		}
	}

}

Third:

将任务从线程中分离出来,哪个线程需要工作,就将任务交给谁,操作方便。

/* 
   实例:四个售票员卖票
   分析:创建4个线程---四个售票员
        操作一份数据
*/
public class Demo {
	public static void main(String[] args) {
		//1.先创建任务类对象
		Ticket ticket = new Ticket();
		//2.创建线程对象,并将任务交给线程
		//JavaApi中对Thread类run()方法的解释:
                //如果该线程是使用独立的 Runnable 运行对象构造的,
                //则调用该 Runnable 对象的 run 方法;否则,该方法不执行任何操作并返回。
                //为了将任务和线程分离,java做了一个Runnable的接口
                //实现了这个接口的类可以作为参数传给线程
		//所以说明任务类中的run方法优先级高于Thread内部的run()
		Thread thread1 = new Thread(ticket);
		Thread thread2 = new Thread(ticket);
		Thread thread3 = new Thread(ticket);
		Thread thread4 = new Thread(ticket);
		//3.开启线程
		thread1.start();
		thread2.start();
		thread3.start();
		thread4.start();
		
	}
}

//创建任务类
class Ticket implements Runnable{
	//所有的线程共享num
    int num = 20;
	public void run() {
	    for(int i=0;i<5;i++){
	    	System.out.println(Thread.currentThread().getName()+"   i:"+i+"  "+ --num);
	    }
	}
}

	

线程注意点:

		Thread thread1 = new Thread();
		Thread thread2 = new Thread(thread1);//将thread1当做任务处理了
		thread1.start();//调用的是thread1的run()方法
		thread2.start();//调用的是thread1的run()方法
		//匿名子类对象也可以工作
		new Thread(){
			public void run() {
				
			}
		}.start();
		

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值