前言
多线程并发这块的东西很重要,同样也很难,虽然是在J2SE中学习的知识,但是也只会基本的启动,了解基本的生命周期而已,并发这一块的东西基本还是不会,但是大部分公司都要求会并发,一般工作两三年的程序员也不一定搞得很清楚,所以自己开始尝试稍稍深入一下多线程并发编程,从多线程基本一步步到并发,不扯淡了,开始。
常见线程启动的几种方式
1、继承Thread类
2、实现Runnable接口
– 其他变种类似,比如匿名内部类的形式。。
package test01;
public class ThreadTest {
public static void main(String[] args) {
// 当然类直接继承Thread和实现Runnable接口的那种就不演示了
// 第一种,继承Thread
Thread t1 = new Thread(){
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1:"+Thread.currentThread().getName());
// 这里可以使用this,因为这个是Thread的匿名内部类,this表示Thread这个对象,
// 但是一般不这样使用,一般还是使用上面的方式
System.out.println("2:"+this.getName());
}
}
};
t1.start();
// 第一种,实现Runnable
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3:"+Thread.currentThread().getName());
// 这里不能使用this.getName() 因为this表示的是Runnable这个对象
}
}
});
t2.start();
// 思考:这种方式考虑下,会调用哪个Run方法,提示:面向对象,方法覆盖
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("4:"+Thread.currentThread().getName());
}
}){
@Override
public void run() {
System.out.println("5:"+Thread.currentThread().getName());
}
}.start();
}
}
另外这里给出Thread类的run方法
private Runnable target;
@Override
public void run() {
if (target != null) {
target.run();
}
}
上面的思考应该是调用的“5”那个run方法,因为继承Thread类,自己写的run方法会覆盖掉父类的run方法
分析以上两种实现方法:
第一种,继承Thread: 其实就是覆盖掉了父类Thread的run方法,调用的时候调用的肯定是子类(继承Thread类)的run方法啦第二种,实现Runnable:
Runnable对象实现的run方法,其实是将Runnable对象通过Thread的构造函数传入到Thread类中,如果Runnable对象不为null的话,就调用Runnable对象中的run方法。
多线程机制会提高程序的运行效率吗?
不一定,多线程又不能提高CPU的主频,也就是单位时间能够执行的指令数目,如果是一个单线程的任务,CPU也只能处理单线程的话,做成多线程去处理的话,可能会降低运行的效率,比如一个人,三张桌子,分别在一个桌子做一个馒头,然后去另外一张桌子继续做,还是只在一张桌子上面做要快了?明显当然是在一张桌子上面做要快,因为不停的跑到其他桌子需要时间,也就是CPU切换线程需要时间。