《黑马程序员》 传统创建线程方式回顾
2014-03-27 15:56
309 查看
------- android培训、java培训、期待与您交流! ----------
public class TraditionThread { public static void main(String[] args) { Thread thread = new Thread(); thread.start(); // 我们直接newThread创建出来的线程,它会去找Thread类里面的run方法 // 我们因为没有代码,所以这个线程的生命就很短,一出来就死亡了 // 其实Thread的内部是这样实现的 /* * public void run() { if (target != null) { target.run(); } } * 因为Thread里面run方法内部的代码什么都没有。所以线程开启了就死亡了 */ /** * 传统的创建线程的第一种方式: 直接new thread的子类 子类唯一比唯一多的一个功能就是子类可以覆盖父类的代码 */ // 我们想让我们的线程执行我们自己的代码 // 我们就要创建Thread的子类,然后覆盖父类的run方法。即把要执行的代码写在 // 覆盖的run方法里面 Thread thread2 = new Thread() { @Override public void run() { while (true) { try { Thread.sleep(10); // 我们让线程休眠10毫秒 } catch (InterruptedException e) { e.printStackTrace(); } // 我们让当前的线程不停的执行一个操作 System.out.println("thread_:" + Thread.currentThread().getName() + "...Id:" + Thread.currentThread().getId()); // 不停的打印当前线程的名字 // 这样线程会处于很累的状态。我们让线程悠着点。不让它执行的那么快 } } }; thread2.start(); /** * 传统的创建线程的第二种方式: 把线程要执行的任务封装到Runable对象的run方法中。 * 然后将Runnable对象传递给Thread的构造方法。 * * 现在我们来理解一下为什么会这样? 因为Thread中的run方法中实现的原理是: public void run() { if * (target != null) { target.run(); } } * 这样也就是说我们上一个的操作是new了一个Thread的子类并且覆盖了父类里面的 run方法。在运行的时候是这样的,我们直接new * Thread是没有任何作用的。因为 里面的run方法,只是判断runnable对象是否存在,直接存在,则调用这个ruuable * 对象的run方法。我们直接new Thread的时候就是调用它里面的run方法里面的代码。 这里什么都没有。而我们在new * Thread子类的时候,覆盖了Thread中run方法里面的代码 所以就执行我们的代码。 * * * 当Thread中的target对象不为空的时候,它就会在Thread的run方法中去执行target的run方法里面的内容。 * 这里的target就是一个Runnable对象。 * * target赋值是通过init方法进行赋值的。它将传递给init方法的runable对象赋值给了thread里面的成员变量 * target,现在我们就是要看的是在哪里调用的这个方法 */ Thread thread3 = new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); // 我们让线程休眠10毫秒 } catch (InterruptedException e) { e.printStackTrace(); } // 我们让当前的线程不停的执行一个操作 System.out.println("thread_:" + Thread.currentThread().getName() + "...Id:" + Thread.currentThread().getId()); // 不停的打印当前线程的名字 // 这样线程会处于很累的状态。我们让线程悠着点。不让它执行的那么快 } } }); thread3.start(); /** * 有一个分析题,我们下面的代码,它执行的会是哪个里面的代码 * 我们得出的结论是它会去执行子类里面的代码 * new Thread(runnable.run){run}.start(); * 创建了一个子类,它的start方法一调用,它就执行了 * 分析如下: * 在创建这个对象的时候,如果子类覆盖了父类的run方法,就直接执行子类 * 中的run方法,就不会再去找父类了,如果子类中没有覆盖父类中的run方法, * 它就会去找Thread类中的Runnable,找到Runnable之后,它就会去调用Runnable * 接口接口实现中的run方法 */ new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); // 我们让线程休眠10毫秒 } catch (InterruptedException e) { e.printStackTrace(); } // 我们让当前的线程不停的执行一个操作 System.out.println("thread_:" + Thread.currentThread().getName() + "...Id:" + Thread.currentThread().getId()); // 不停的打印当前线程的名字 // 这样线程会处于很累的状态。我们让线程悠着点。不让它执行的那么快 } } }) { public void run() { while (true) { try { Thread.sleep(10); // 我们让线程休眠10毫秒 } catch (InterruptedException e) { e.printStackTrace(); } // 我们让当前的线程不停的执行一个操作 System.out.println("thread_:" + Thread.currentThread().getName() + "...Id:" + Thread.currentThread().getId()); // 不停的打印当前线程的名字 // 这样线程会处于很累的状态。我们让线程悠着点。不让它执行的那么快 } }; }.start(); // 打印主线程 System.out.println("主线程:__名称:" + Thread.currentThread().getName() + "...Id:" + Thread.currentThread().getId()); /** * 其实传统的两种的方式创建的线程最终起作用的还是Thread类 * 一种是使用了Thread的子类,覆盖了父类中的run方法 * 另外一个是把线程要执行的任务封装在Runnable对象的run方法里面在 * 然后把Runnable对象传递给了Thread类的构造方法。 * 为什么我们在写程序的过程中都是使用的第二种了? * 这是因为第二种更接近对面向对象的思想。 * 因为我们是把任务封装在了Runnable对象,然后Thread又调用了Runnable这个对象 * 即是Thread这个类在指挥Runnable干事情。 */ }
相关文章推荐
- java多线程之创建线程的两种传统方式
- 黑马程序员:创建线程的两种方式
- 【java并发】传统线程技术中创建线程的两种方式
- 【java多线程与并发库】---传统java多线程<2> 线程创建方式
- Java并发01----传统线程中创建线程的两种方式
- 创建线程的两种传统方式
- 【java并发】传统线程技术中创建线程的两种方式
- 传统的创建线程的两种方式
- 黑马程序员:创建线程的两种方式
- 【java多线程与并发库】---传统java多线程<2> 线程创建方式
- 1.传统创建线程的方式
- 创建线程的两种传统方式
- 黑马程序员-线程(两种创建方式)、定时器
- 黑马程序员——多线程—创建线程的3种方式
- 传统线程的创建方式
- 创建线程的两种传统方式
- Java传统线程创建方式和互斥
- 传统创建线程的两种方式
- java多线程01:创建线程的两种传统方式
- 黑马程序员-创建线程方式