Java并发编程的暗自努力(二)走进代码
2017-08-27 10:23
169 查看
创建并运行Java线程
Java线程是一个object类,它的实例都继承自java.lang.Thread或其子类创建线程的办法:
Thread thread = new Thread();
执行线程的办法
thread.start();
编写线程运行时的代码有两种方式:
1. 创建Thread子类
Step 1: 创建Thread子类并重写run方法,run方法在调用start()方法后被执行
public class MyThread extends Thread{ public void run(){ // to do something } }
Step 2: 创建并运行上述子类
MyThread mThread = new MyThread(); mThread.start();
2.实现Runnable接口
Step 1:新建一个实现java.lang.Runable接口的类的实例,实例中的方法可以被线程调用
public class MyRunnable implements Runable{ public void run(){ // to do something } }
Steo 2:为了执行run()方法,需要在Thread类的构造函数中传入MyRunnable的实例对象
Thread thread = new Thread(new MyRunnable()); thread.start();
两种方法都可以用匿名类的形式实现
Runnable myRunnable = new Runnable(){ public void run(){ System.out.println("Runnable running"); } } Thread thread = new Thread(myRunnable); thread.start();
创建子类还是实现Runnable接口?——No Answer
如果实现Runnable接口这种方法,因为线程池可以有效的管理实现了Runnable接口的线程,如果线程池满了,新的线程就会排队等候执行,直到线程池空闲出来为止而如果线程是通过实现Thread子类实现的,这将会复杂一些
有时我们要同时融合实现Runnable接口和Thread子类两种方式。例如,实现了Thread子类的实例可以执行多个实现了Runnable接口的线程。一个典型的应用就是线程池。
常见错误:调用run()方法而非start()方法
创建并运行一个线程所犯的常见错误是调用线程的run()方法而非start()方法,如下所示:Thread newThread = new Thread(MyRunnable()); newThread.run(); //should be start();
起初你并不会感觉到有什么不妥,因为run()方法的确如你所愿的被调用了。但是,事实上,run()方法并非是由刚创建的新线程所执行的,而是被创建新线程的当前线程所执行了。也就是被执行上面两行代码的线程所执行的。想要让创建的新线程执行run()方法,必须调用新线程的start方法。
其实,很显然,使用run()的调用,它只不过是在本线程中调用了该类内的方法罢了
线程名
创建一个线程的时候,可以给线程起一个名字。它有助于我们区分不同线程MyRunnable runnable = new MyRunnable(); Thread thread = new Thread(runnable, "Name A"); thread.start(); System.out.println(thread.getNaem());
另外,MyRunnable并非Thread的子类,所以它没有getName()方法。可以通过如下代码获得当前线程的名字:
String threadName = Thread.currentThread().getName();
简单的一个示例
public class TryThread { public static void main(String args[]){ System.out.println(Thread.currentThread().getName()); for(int i=0; i<10; i++){ new Thread("" + i){ @Override public void run() { System.out.println("Thread:" + getName() + "running"); } }.start(); } } }
相关文章推荐
- Java并发编程的暗自努力(五)Java内存模型
- 探索并发编程(二)------写线程安全的Java代码
- 【Java并发编程】:深入Java内存模型——happen-before规则及其对DCL的分析(含代码)
- 【Java并发编程】之十二:线程间通信中notifyAll造成的早期通知问题(含代码)
- 【Java并发编程】之九:死锁(含代码)
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)
- 【Java并发编程】之十八:第五篇中volatile意外问题的正确分析解答(含代码)
- 转: 【Java并发编程】之十三:生产者—消费者模型(含代码)
- 【Java并发编程】之十三:生产者—消费者模型(含代码)
- 【Java并发编程】之六:Runnable和Thread实现多线程的区别(含代码)
- 【Java并发编程】之五:volatile变量修饰符—意料之外的问题(含代码)
- 【Java并发编程】之五:volatile变量修饰符—意料之外的问题(含代码)(r)
- 【Java并发编程】之十九:并发新特性—Executor框架与线程池(含代码)
- 【Java并发编程】之十三:生产者—消费者模型(含代码)
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)
- 【Java并发编程】之十八:第五篇中volatile意外问题的正确分析解答(含代码)
- 【Java并发编程】之十一:线程间通信中notify通知的遗漏(含代码)
- 【Java并发编程】之十二:线程间通信中notifyAll造成的早期通知问题(含代码)
- 【Java并发编程】之三:线程挂起、恢复与终止的正确方法(含代码)