【多线程】——Thread VS Runnable

进程和线程的关系

    多个线程构成一个进程,线程是进程中的一个元素,例如QQ.exe查看电脑进程的时候发现只有一个进程,但是我们可以同时和多个用户聊天交流,而且可以一边聊天,刷空间之类。对每一个用户的聊天就是一个线程,多个用户的互动构成进程。

    演示一个不使用多线程的Demo,也就是单线程

public class SingleDemo{
	public static void main(String[] args){
		MyThread myThread = new MyThread();
		myThread.run();
		while(true){
			System.out.println("Main方法在运行");
		}
	}
}
	
	class MyThread{
		public void run(){
			while (true){
				System.out.println("MyThread类的run()方法在运行");
			}
		}
	}

  根据demo可以知道mian中的run方法永远都不可能被执行

   

      一张图说明何为单线程和多线程!


 从图中很清晰表明我们使用多线程的原因

继承Thread创建多线程

public class DemoThread{
	public static void main(String[] args){
		MyThread myThread = new MyThread();
		myThread.start(); //通过start()开启了一个新的线程
		while(true){
			System.out.println("run()方法在运行");
		}
	}
}
class MyThread extends Thread {
	public void run(){
		while(true){
			System.out.println("MyThread类的run()方法在运行");
		}
	}
}
显示结果


实现Runnable接口创建多线程

public class DemoRunnable{
	public static void main(String[] args){
		RunnableDemo runnable = new RunnableDemo();
		Thread mythread = new Thread(runnable);
		mythread.start();
		while(true){
			System.out.println("main类的run()方法在运行");
		}
	}
}
class RunnableDemo implements Runnable{
	public void run(){
		while(true){
			System.out.println("RunnableDemo类的run()方法在运行");
		}
	}
}
显示结果

        

目前实现多线程的方式继承Thread,另一种实现Runnable接口。

上述Demo是利用Thread(Runnable target)这个构造函数实现的,Runnable是一个接口其中只有一个run()方法,在调用Thread时,看一下Thread的类结构就知道,其实实现的是接口Runnable中的方法。所以两种多线程实现方式具有多态关系。

Thread VS Runnable

    先说一个例子,火车站售票会牵扯到一个资源共享的问题,资源就是车票,每个售票都相当与一个线程,假如有100张票,每张票理论上都只能买一个人,下面看Thread和Runnable的处理方式

继承Thread

public class DemoExceple{
	public static void main(String[] args){
		new TicketWindow().start();
		new TicketWindow().start();
		new TicketWindow().start();
		new TicketWindow().start();
	}
}
class TicketWindow extends Thread{
		private int tickets = 100;
		public void run(){
			while(true){
				if(tickets>0){
					Thread th = Thread.currentThread();
					String name = th.getName();
					System.out.println(name+"正在发售第"+tickets--+"张票");
				}
			}
		}
	}
运行结果

     

    根据这个运行结果,发现每一张票都被重复卖了四次,明显这种多线程的方式并不太适合资源共享的问题。

实现Runnable接口

public class RunnableDemoTest{
	public static void main(String[] args){
		TicketWindow tw = new TicketWindow();
		new Thread(tw,"窗口1").start();
		new Thread(tw,"窗口2").start();
		new Thread(tw,"窗口3").start();
		new Thread(tw,"窗口4").start();
	}
	
}
class TicketWindow implements Runnable{
	private int tickets = 100;
	public void run(){
		while(true){
			if(tickets>0){
				Thread th = Thread.currentThread();
				String th_name = th.getName();
				System.out.println(th_name+"正在发售第"+tickets--+"张票");
			}
		}
	}
}
运行结果

       

根据运行结果发现使用Runnable接口刚好能解决我们资源共享的问题。

为什么Thread不行,而Runnable就可以?

Thread方式中创建了4个Thread对象,4个线程分别执行4个对象中的代码,所以4个线程是独立的去完成卖票任务

Runnable方式,同样创建了4个Thread对象,但是只有一个Runnable对象,4个Thread对象共享Runnable中的代码,因此,便会出现4个线程同时完成卖票的任务的结果。如果创建4个Runnable对象,分别做为参数传入4个Thread中,结果会和Thread方式一样的。

    其实实现Runnable接口的线程中如果出现休眠,在资源共享也会出现非线程安全的问题,最根本的解决方式资源共享的问题还是同步锁(synchronized)的机制。

结论

   根据上述两种情况,其实Runnable和Thread能完成相同的功能,毕竟Thread也是实现Runnable,两者根本的区别一个是继承,一个是实现。

1、Runnable相当于一个作业,而Thread才是真正的处理线程。通过new Thread(Runnable target)把作业交给线程去处理,这样达到松耦合的效果,也是符合面向对象中组合的使用。

2、Runnable可以避免Java中单继承的局限性,一个子类继承父类,不能在继承Thread实现多线程,Runnable接口刚好是完美的解决方案。

    整体上来说,用Runnable比Thread好的多。

    小编也是刚刚开始学习,如有错误之处还请指出,不胜感激!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Mandy_i

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

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

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

打赏作者

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

抵扣说明:

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

余额充值