继承和实现两种创建线程的方式对比分析

来源:互联网 发布:cf手游龙爪技能数据 编辑:程序博客网 时间:2024/06/05 09:24
一:创建线程的方式
   方式一:继承Thread类的方式:
* 1.提供Thread类的子类:创建子类继承于Thread类。
 * 2.重写Thread类的run():将此分线程要执行的操作,声明在此run()中。
 * 3.创建Thread类的子类的对象
 * 4.调用此对象的start()方法
          start方法两个作用:①启动分线程②调用对象的run()方法。
    注意:①Thread并不是抽象类,重写run方法是手动加载的,系统不会提醒。
          ②如何创建多线程,可以造多个对象,然后分别启动start方法
          ③重写的run方法不可以抛异常,因为父类中的run方法都没有抛出异常。

1.用继承RUNNABLE接口的形式
  //1.提供Runnable接口的实现类
  class SonTread implements Runnable {
  // 2.重写run():将此分线程要执行的操作,声明在此run()
  @Override
  public void run() {
  for (int i = 1; i <= 100; i++) {
  if (i % 2 == 0) {
  System.out.println(Thread.currentThread().getName() + "**" + i);
  }
  }
  }
}
public class ThreadTest {//测试类
  public static void main(String[] args) {
  // 3.创建实现类的对象
  SonTread sonTread = new SonTread();
  // 4.将此对象作为参数,传递给Thread的构造器,创建Thread类的对象
  Thread t = new Thread(sonTread);
  // 5.通过Thread类的对象,调用start():①启动线程 ②调用run()
  t.start();
  Thread t1 = new Thread(sonTread);
  t1.start();
  Thread t2 = new Thread(sonTread);
  t2.start();
  new Thread(new SonThread(),"线程五").start();
  for (int i = 1; i <= 100; i++) {
  if (i % 2 == 0) {
  System.out.println(Thread.currentThread().getName() + "----" + i);
  }
  }
  }
}
 方式二:实现Runnable接口的方式: 
 * 1.提供Runnable接口的实现类
 * 2.重写run():将此分线程要执行的操作,声明在此run()
 * 3.创建实现类的对象
 * 4.将此对象作为参数,传递给Thread的构造器,创建Thread类的对象
 * 5.通过Thread类的对象,调用start():①启动线程 ②调用当前类的run()
     注意:这里调用的run方法调用的也是Thread类里面的run方法,只是该Thread类中run方法发起了对Runnabl里的run进行了调用(可以调用时因为Thread也实现了Runanlbe接口,所以实际调用的是实现了Runnable接口的分线程中的run方法)。

2.Thread继承方式
  public class ThreadTest {
  public static void main(String[] args) {
  //3.创建Thread类的子类的对象
  SubThread sub1 = new SubThread();
  //4.调用此对象的start():①启动线程 ②调用run()
  sub1.start();
  //问题一:能否使用run()启动一个线程?不能!
  sub1.run();
  //问题二:如何再启动一个分线程?如下的写法是错误的!
  sub1.start();
  //如下的方式再启动一个分线程,是正确的。
  SubThread sub2 = new SubThread();
  sub2.start();

  for(int i = 1;i <= 100;i++){
  if(i % 2 == 0){
  System.out.println(Thread.currentThread().getName() + "--" + i );
  }
  }
  }
  }
  1.提供Thread类的子类
  class SubThread extends Thread{
  //2.重写Thread类的run()
  @Override
  public void run() {
  for(int i = 1;i <= 100;i++){
  if(i % 2 == 0){
  System.out.println(this.getName() + ":" + i);
  }
  }
  }
  }
  3.继承Thread方式的:匿名类对象方式
  new Thread(){
  @Override
  public void run() {
  for(int i = 2;i<100;i*=i){
  System.out.println("fdfd"+i);
  }
  }
  }.start();

  4.Thread类常用构造器。
  Thread():创建新的Thread对象
- Thread(String threadname):创建线程并指定线程实例名

- Thread(Runnable target):指定创建线程的目标对象,它实现了Runnable接口中的run方法

- Thread(Runnable target, String name):创建新的Thread对象
  两种方式的对比:
 *  联系:①启动线程,都需要调用的是Thread类中同一个start().
 *       ②class Thread implements Runnable
            即:线程Thread在内部也实现了Runnable接口。
 *  不同:实现Runnable的方式更好。
 *  原因:实现的方式,不影响类的继承。(解决了单继承的局限性
 *        实现的方式,对于处理多线程的共享数据问题,更方便(因为共享类的一个对象)
补充:
   1.分线程是在主线程(main)帮助下启动执行的。
   2.然后主线程和分线程在cpu中交替执行,只是交替的速度足够快。
   3.线程的建立一定要在main方法里创建,不然主线程无法启动,分线程的创建有问题。每个Java程序都有一个隐含的主线程: main 方法
   4.main方法的启动是一个线程也是一个进程,一个java程序启动后它就是一个进程,进程相当于一个空盒,它只提供资源装载的空间,具体的调度并不是由进程来完成的,而是由线程来完成的。一个java程序从main开始之后,进程启动,为整个程序提供各种资源,而此时将启动一个线程,这个线程就是主线程,它将调度资源,进行具体的操作。Thread、Runnable的开启的线程是主线程下的子线程,是父子关系,此时该java程序即为多线程的,这些线程共同进行资源的调度和执行。
   5.Junit不支持多线程测试,多线程测试要在main()方法里。
   6.补充:关于sleep():相当于将该线程挂起,其他满足条件的线程执行。
       1- 令当前活动线程在指定时间段内放弃对CPU控制,使其他线程有机会被执行,时间到后重排队。
       2- 抛出InterruptedException异常
                   
       
 
阅读全文
0 0
原创粉丝点击