Java---11---多线程的两种创建方式
多线程的两种创建方式:
下面这些东西是API文档中的:
public class Thread
extends Object
implements Runnable
线程 是程序中的执行线程。Java 虚拟机允许应用程序并发地运行多个执行线程。
每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序。
当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法)。Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:
· 调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生。
· 非守护线程的所有线程都已停止运行,无论是通过从对 run 方法的调用中返回,还是通过抛出一个传播到 run 方法之外的异常。
创建新执行线程有两种方法。一种方法是将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。接下来可以分配并启动该子类的实例。例如,计算大于某一规定值的质数的线程可以写成:
class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } }
然后,下列代码会创建并启动一个线程:
PrimeThread p = new PrimeThread(143); p.start();
创建线程的另一种方法是声明实现 Runnable 接口的类。该类然后实现 run 方法。然后可以分配该类的实例,在创建 Thread 时作为一个参数来传递并启动。采用这种风格的同一个例子如下所示:
class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } }
然后,下列代码会创建并启动一个线程:
PrimeRun p = new PrimeRun(143); new Thread(p).start();
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。
---------------------------------------------
线程的创建方式:
1.继承Thread
2.实现Runnable
第一种方式:继承Thread类
实现步骤:
1.自定义类继承Thread
2.复习Thread中的run()方法
3.创建该类的对象,调用start()方法,开启线程并调用run方法
简单实现:
class MyThread extends Thread { public void run () { for (int i = 0; i < 100; i++) { System.out.println("MyThread.run()..."+i); } } } public class THREAD { public static void main (String[] args) { MyThread a = new MyThread(); a.start(); for (int j = 0; j < 100; j++) { System.out.println("THREAD.main()----"+j); } } }
多运行几次会发现:
i所在的线程和j所在的线程会交替运行
但是每次运行的结果却是不一样的
这就是多线程的随机性
为什么要覆盖run方法?
Thread 用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码
该存储功能就是run方法。
第二种创建方式:实现Runnable
Runnable是一个简单的接口,该接口中只有一个抽象方法:run方法。
实现步骤:
1.定义一个实现Runnable接口的类
2.覆盖run方法
3.创建该类对象,并以该类对象为参数创建Thread类的对象,从而创建了一个线程
4.调用start方法,开启线程并调用run方法。
简单创建:
class MyThread implements Runnable { public void run () { for (int i = 0; i < 50; i++) { System.out.println("MyThread.run()..."+i); } } } public class THREAD { public static void main (String[] args) { MyThread a = new MyThread(); Thread a1 = new Thread(a); Thread a2 = new Thread(a); Thread a3 = new Thread(a); Thread a4 = new Thread(a); a1.start(); a2.start(); a3.start(); a4.start(); } }
该例子中创建了四个线程,能够实现四个线程的交替运行,但是却看不出是哪个线程执行的,
调用Thread类中的getName方法可以解决这个问题
System.out.println(Thread.currentThread().getName()+"..."+i);
currentThread():获取当前线程对象
线程的名字
Thread-0
Thread-1
...
线程都有自己默认的名称,Thread-编号 编号从0开始
也可以自己定义线程的名称。
class MyThread implements Runnable { private String name; public MyThread(String name) { this.name = name; } public String GetName() { return name; } public void run () { for (int i = 0; i < 50; i++) { System.out.println(this.GetName()+"..."+i); } } } public class THREAD { public static void main (String[] args) { MyThread a = new MyThread("My"); MyThread b = new MyThread("Your"); Thread a1 = new Thread(a); Thread a2 = new Thread(b); a1.start(); a2.start(); } }
如果用的是 继承Thread类的方式 直接用super就可以,
因为Thread类中有getName这个方法,通过构造函数初始化线程,然后直接调用getName方法就行。
class MyThread extends Thread { private String name; public MyThread(String name) { super(name); } // public String GetName(){ // return name; // } public void run () { for (int i = 0; i < 50; i++) { System.out.println(Thread.currentThread().getName()+"..."+i); } } } public class THREAD { public static void main (String[] args) { MyThread a = new MyThread("My"); MyThread b = new MyThread("Your"); // Thread a1 = new Thread(a); // Thread a2 = new Thread(b); a.start(); b.start(); } }
两种方式的区别:
第一种:继承Thread的方法:
1.缺点:Java语言只允许单继承,所以该类继承了Thread之后就不可以再继承其他的类了
2.优点:编写简单。
第二种:实现Runnable接口的方式:
1.缺点:编写稍显复杂
2.优点:
a) 避免由于单继承带来的局限性
b) 有利于代码的健壮性,代码能够被多个线程共享,代码与数据是独立的
代码存放的位置:
继承Thread方式:线程代码存放于Thread子类的run方法中
实现Runnable方式:线程代码存放于接口子类的run方法中。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。