[Java][实现多线程的三种方式]

本系列学习笔记简介

传智播客的毕向东Java基础教程是免费公开的一份面向初学者的Java学习教程。在我学习毕老师的Java基础教程过程中,苦于其并没有附带练习题,总觉得学的‘轻飘飘’的,所以决定每天看完的一些内容,总在接下来的几天里找一些时间写下来,看看自己还记得多少,看看自己哪些知识点理解的不透彻。希望本系列学习笔记在帮助自己理清思路,理顺知识点的同时,也能够帮助其他在学习Java的同学。欢迎大家在评论区讨论相关内容。

多线程的继承Thread类实现

进程线程简介

进程可以认为是一个正在运行中的程序,你打开任务管理器就可以看到进程。而线程是这个进程中,为了完成一些任务而相互独立进行的代码集合,比如你在360安全卫士中打开安全检查的同时又可以清扫垃圾,这时你就开启了两个线程。

多线程卖票介绍

我们这里通过一个卖票例子来讲解多线程的继承Thread类实现。我们假设共有100张编号为1到100的票,在命令行打印一个数字就视为卖出了对应编号的票,我们首先采用继承Thread类来实现。
思路:创建一个类来继承Thread类,在子类中重写run()方法来覆盖父类Thread中的run()方法。

代码块

错误代码块
class Ticket extends Thread
{
	private int num = 100;
	public void run()
	{
		while(true)
		{
			if(num>0)
				System.out.println(Thread.currentThread().getName()+"....."+"num="+num--);
		}
	}
}
class TicketDemo 
{
	public static void main(String[] args) 
	{
		Ticket t1 = new Ticket();
		Ticket t2 = new Ticket();
		t1.start();
		t2.start();
	}
}

上述代码的部分运行结果为:
命令行结果
我们看到线程0与线程1卖出了同样的票号,这是我们不希望看到的,这100号座位旅客0坐还是旅客1坐合适啊?究其原因,是因为我们new了两个Ticket对象,每生成一个Ticket对象,JVM虚拟机的堆内存中都会有属于该对象的成员变量num=100,所以num- -的时候每个票号都会出现两次。我们可以选择把num变为静态变量,这样它就会被JVM存储在方法区中,被Ticket对象所共享。

正确代码块
class Ticket extends Thread
{
	private static int num = 100;//我们只是在这里加上了static关键字
	public void run()
	{
		while(true)
		{
			if(num>0)
				System.out.println(Thread.currentThread().getName()+"....."+"num="+num--);
		}
	}
}
class TicketDemo 
{
	public static void main(String[] args) 
	{
		Ticket t1 = new Ticket();
		Ticket t2 = new Ticket();
		t1.start();
		t2.start();
    }
}

注意:这个所谓的正确代码块,还是存在安全隐患的,因为如果线程0执行到num=1到了判断语句之后,这时如果线程1进来,那么会输出Thread=1…num=1,随后切换到线程0,输出就会为Thread=0…num=0

通过接口Runnable实现多线程

由于Java不允许多继承,所以当一个类已经有父类时就不能够继承Thread类了,这时要通过接口Runnable实现多线程。使用实现接口Runnable的对象创建线程,当启动线程时,在独立运行的线程中就会调用对象的run方法。

代码块

class ThreadDemo 
{
	public static void main(String[] args) 
	{
		Ticket t = new Ticket();
		// 使用实现Runnable接口的对象创建一个线程
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		//启动该线程,将导致在独立运行的线程中调用该对象的run方法
		t1.start();
		t2.start();
	}
}
class Ticket implements Runnable
{
	public int num=100;
	public void run()
	{
		while(true)
		{
			if(num>0)
			System.out.println(Thread.currentThread().getName()+"..."+num--);
		}
	}
}

命令行运行结果为

最后要注意的几点:
1.上述实现多线程是不安全的,还需要通过同步关键字synchronized来保证安全。
2.实现多线程常见的有三种方式,这里介绍了通过继承Thread类实现,通过实现接口Runnable实现,最后一种我们有机会再说。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值