说道多线程
就得来认识下咱们经常说道的几个概念。
进程: 是一个静态的概念,它本身是不能动的,每个进程都是有一个主方法的执行路径,这个路径就是一个具体的线程。
线程:不同的程序执行路径。
多线程是我们处理多任务的强有力工具。
线程和进程的不同:
- 进程有独立运行的程序,有自己的变量,且不同进程不能共享。
- 线程是运行在进程内部的。不同的线程之间可以在进程范围内共享数据。
- 线程是通过并行处理给用户带来更好的使用体验。
实现进程的两种方式:
- 继承java.lang.Thread,并重写它的run()方法,将线程的执行主体放入其中。
- 实现java.lang.Runnable接口,实现它的run()方法,并将线程的执行主体放入其中。使用runnable接口可以为多个线程提供共享的数据
java代码
继承Thread类实现线程实例
public class TestThread { public static void main(String args[]) { TestThread1 r = new TestThread1 (); r.start(); for(int i=0; i<5; i++) { System.out.println("Main Thread:------" + i); } } } class TestThread1 extends Thread { public void run() { for(int i=0; i<5; i++) { System.out.println("Runner1 :" + i); } } }
实现Runnable接口实现多线程实例
public class TestThread { public static void main(String args[]) { //实例化接口实现类 Runnable1 r = new Runnable1 (); //调用构造方法创建线程 Thread t = new Thread(r); t.start(); for(int i=0; i<5; i++) { System.out.println("Main Thread:------" + i); } } } class Runnable1 implements Runnable { public void run() { for(int i=0; i<5 i++) { System.out.println("Runner1 :" + i); } } }
注意:
这两种实现方式的区别并不大。继承Thread类的方式实现起来较为简单,但是继承它的类就不能再继承别的类了,因此也就不能继承别的类的有用的方法了。而使用是想Runnable接口的方式就不存在这个问题了,而且这种实现方式将线程主体和线程对象本身分离开来,逻辑上也较为清晰,所以推荐大家更多地采用这种方式。
如何启动线程:
继承Thread调用
public static void main(String args[]) { TestThread1 r = new TestThread1 (); r.start(); }
实现Runnable接口的调用
public static void main(String args[]) { //实例化接口实现类 Runnable1 r = new Runnable1 (); //调用构造方法创建线程 Thread t = new Thread(r); t.start(); }
两者这两种启动方法原理是一样的。首先都是调用bending启动一个线程,其次是在线程里执行目标对象的run方法。
当我们采用Runnable接口实现线程时,调用thread(Runnable garget)构造,参数为接口类型的,Runnable,所以线程启动时,实例的run()方法就被执行了。
构造方法摘要
- Thread(Runnable target)
- 分配新的 Thread 对象。
如果我们采用的是继承Thread类的方式,那么这个target就是线程对象自身,如果我们采用的是实现Runnable接口的方式,那么这个target就是实现了Runnable接口的类的实例。
两者的区别:
如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享
public class thread3{ public static void main(String[] args) { hello h1 = new hello(); hello h2 = new hello(); hello h3 = new hello(); h1.start();//每个线程都各卖了5张,共卖了15张票 h2.start();//但实际只有5张票,每个线程都卖自己的票 h3.start();//没有达到资源共享 } } class hello extends Thread { public void run() { int count = 5; for (int i = 0; i < 7; i++) { if (count > 0) { System.out.println("count= " + count--); } } } }
效果图
大家可以想象,如果这个是一个买票系统的话,如果count表示的是车票的数量的话,说明并没有实现资源的共享
我们换位Runnable接口 class MyThread implements Runnable{ private int ticket = 5; //5张票 public void run() { for (int i=0; i<=20; i++) { if (this.ticket > 0) { System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--); } } } } public class lzwCode { public static void main(String [] args) { MyThread my = new MyThread(); new Thread(my, "1号窗口").start(); new Thread(my, "2号窗口").start(); new Thread(my, "3号窗口").start(); } }
效果图
所以
实现Runnable接口比继承Thread类所具有的优势:
- 1):适合多个相同的程序代码的线程去处理同一个资源
- 2):可以避免java中的单继承的限制
- 3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
以上几点只是线程的基本概念。还没涉及同步,进行状态的装换。初认识java。希望大家多多指点。