多线程精品解读

一个程序运行后至少有一个进程,一个进程可以包含多个线程,至少有一个线程

原理

一个软件在某一时间里运行,其实CPU只运行了一个进程,但我们感觉很多软件都在运行呢,其实是CPU在做着高速的切换,我们人是很难看出来的,对CPU而言,一时刻只能运行一个进程。
多线程可以解决一个主线程负责执行其中的一个循环,由另一个线程负责其他代码的执行

创建线程方式——继承Thread类h

继承Thread就要实现里面的run方法

创建线程的步骤:

  1. 定义一个类继承Thread
  2. 重写run方法
  3. 创建子类对象
  4. 调用start方法,开启线程并让线程执行,同时告诉JVM去调用run方法
class Demo extends Thread  //继承Thread
{
	String name;
	Demo(String name)
	{
		this.name = name;
	}
	//复写其中的run方法
	public void run()
	{
		for (int i=1;i<=20 ;i++ )
		{
			System.out.println("name="+name+",i="+i);
		}
	}
}
class ThreadDemo 
{
	public static void main(String[] args) 
	{
		//创建两个线程任务
		Demo d = new Demo("小强");
		Demo d2 = new Demo("旺财");
		//d.run(); 这里仍然是主线程在调用run方法,并没有开启两个线程
		//d2.run();
		d2.start();//开启一个线程
		d.run();//主线程在调用run方法
	}
}

线程中调用run方法和调用start方法区别:
线程对象调用run方法是不开启线程的,仅是对象调用调用方法,程序调用start开启线程,并且让JVM调用run方法在开启的线程中执行

创建线程的目的
建立单独的执行路径,让多部分代码实现同时执行。也就是说线程创建并执行需要给定的代码(线程的任务)。对于之前所讲的主线程,它的任务定义在main函数中。自定义线程需要执行的任务都定义在run方法中。Thread类中的run方法内部的任务并不是我们所需要,只有重写这个run方法,既然Thread类已经定义了线程任务的位置,只要在位置中定义任务代码即可。所以进行了重写run方法动作。

当执行线程的任务结束了,线程自动在栈内存中释放了。但是当所有的执行线程都结束了,那么进程就结束了。

获取线程的名称
Thread.currentThread()获取当前线程对象

Thread.currentThread().getName();获取当前线程对象的名称

当主线程执行完成了,并不代表程序就结束了,如果此时还有其他的线程正在执行,程序就仍然在执行
当一个线程发生异常,其他线程还是会继续执行的,异常只会影响到异常所属的线程

创建线程的第二种方式——实现Runnable接口

步骤:

  1. 定义类实现Runnable接口
  2. 覆盖接口中的run方法
  3. 创建Thread类的对象
  4. 讲Runnable接口的子类对象作为参数传递给Thread类的构造函数
  5. 调用Thread类的start方法开启线程
class Demo implements Runnable
{
	private String name;
	Demo(String name)
	{
		this.name = name;
	}
	//覆盖了接口Runnable中的run方法。
	public void run()
	{
		for(int i=1; i<=20; i++)
		{			System.out.println("name="+name+"..."+Thread.currentThread().getName()+"..."+i);
		}
	}
}
class ThreadDemo2 
{
	public static void main(String[] args) 
	{
		//创建Runnable子类的对象。注意它并不是线程对象。
		Demo d = new Demo("Demo");
		//创建Thread类的对象,将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
		Thread t1 = new Thread(d);
		Thread t2 = new Thread(d);
		//将线程启动。
		t1.start();
		t2.start();
		System.out.println(Thread.currentThread().getName()+"----->");
		System.out.println("Hello World!");
	}
}

实现Runnable的原理

继承Thread类和实现Runnable接口有什么区别
实现Runnable接口,避免了继承Thread类的单继承局限性,覆盖Runnable接口中的run方法,将线程代码定义到run方法里,创建Thread类的对象,只有创建Thread类的对象才可以创建线程。线程任务已经被封装到了Runnable的run方法里面,而这个run方法所属于Runnable接口的子类对象,所以将这个子类对象作为参数传递给Thread的构造函数,这样线程对象创建时就可以明确要运行的线程任务。

实现Runnable的好处

第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。实现Runnable接口的方式,更加符合面向对象,线程分为了两部分,一部分是线程对象,一部分是线程任务,继承Thread类,线程对象和线程任务耦合在了一起,一旦创建Thread类的子类对象,既是线程对象,又是线程任务。实现Runnable接口,将线程任务单独分离出来封装成对象,类型就是Runnable接口类型,Runnable接口对线程任务和线程对象进行解耦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值