前几天面试的时候被问到的一些问题,整理一下,下次注意
1.多线程—thread和runable的区别?
java中有两种实现多线程的方式:
1. 一种是通过继承Thread类,同时重写run()方法。但是java中,只允许单继承,也就是一个类只能继承一个父类,使得该方式具有一定的局限性.
2. 另一种是实现Runnable类接口的run()方法,再结合Thread类来实现多线程。
两种方式最终都是通过调用start()方法来实现多线程。切记不能直接调用Thread类或Runnable对象的run()方法,因为直接调用run()方法,只会执行同一个线程中的任务,而不会启动新线程。调用start()方法将会创建一个执行run()方法的线程。
继承Thread—
/**
* 多线程之继承thread
*
*
*/
public class ExtendsThread extends Thread {
private String name;
private int ticket = 5;
public ExtendsThread(String name) {
super();
this.name = name;
}
public void run() {
for (int i = 0; i < 10; i++) {
if (ticket > 0) {
System.out.println("线程开始:" + this.name + ",,,卖票:i="
+ this.ticket--);
}
}
}
}
/**
* 继承thread测试类
*
*/
public class TestExtendsThread {
public static void main(String[] args) {
Thread t1=new ExtendsThread("线程A");
Thread t2=new ExtendsThread("线程B");
t1.run();
t2.run();
}
}
调用run方法结果
线程开始:线程A,,,卖票:i=5
线程开始:线程A,,,卖票:i=4
线程开始:线程A,,,卖票:i=3
线程开始:线程A,,,卖票:i=2
线程开始:线程A,,,卖票:i=1
线程开始:线程B,,,卖票:i=5
线程开始:线程B,,,卖票:i=4
线程开始:线程B,,,卖票:i=3
线程开始:线程B,,,卖票:i=2
线程开始:线程B,,,卖票:i=1
这个结果说明了继承先执行第一个对象的run方法,执行完了再执行第二个run方法,没有开启新的线程
调用start方法结果
线程开始:线程B,,,卖票:i=5
线程开始:线程B,,,卖票:i=4
线程开始:线程B,,,卖票:i=3
线程开始:线程A,,,卖票:i=5
线程开始:线程B,,,卖票:i=2
线程开始:线程A,,,卖票:i=4
线程开始:线程A,,,卖票:i=3
线程开始:线程A,,,卖票:i=2
线程开始:线程A,,,卖票:i=1
线程开始:线程B,,,卖票:i=1
这个结果说明了start方法开启了一个线程去执行run方法。两个线程完成交互,两个线程的run方法是独立的,对应的成员变量也是独立的,资源没有共享
实现runable接口–
/**
* 多线程之实现runable接口
*
*/
public class ImpRunable implements Runnable {
private int ticket = 5;
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if (ticket > 0) {
System.out.println("线程开始:" + Thread.currentThread().getName()
+ ",卖票:" + this.ticket--);
}
}
}
}
package com.wode.TestPro;
/**
* 测试实现runable接口
*
* @author Administrator
*
*/
public class TestRunable {
public static void main(String[] args) {
ImpRunable r=new ImpRunable();
Thread t1=new Thread(r,”线程A”);
Thread t2=new Thread(r,”线程B”);
t1.start();
t2.start();
}
}
实现runable接口结果为
线程开始:线程A,卖票:5
线程开始:线程B,卖票:4
线程开始:线程A,卖票:3
线程开始:线程B,卖票:2
线程开始:线程A,卖票:1
这个结果我们知道了,使用runable对象时,runable定义的子类没有start方法,只有thread类中才有,而thread类中有一个构造方法public Thread(Runnable target),此构造方法接收runable的子类实例,通常说就是可以通过thread类来启动runable实现多线程,每个线程调用的都是ImpRunable 对象的run方法,访问的都是同一个对象中成员变量的实例。
总结
实际开发中我们通常采用Runnable接口来实现多线程。因为实现Runnable接口比继承Thread类有如下好处:
1. 避免继承的局限,一个类可以实现多个接口,但是类只能继承一个类。
2. Runnable接口实现的线程便于资源共享。而通过Thread类实现,各自线程的资源是独立的,不共享