常用的实现多线程的两种方式 Thread 和 Runnable 为什么是常用的那,因为还可以通过juc包里面的线程池来实现多线程,
Thread和Runnable简介
Runnable 是一个接口 该接口中只包含了一个Run()方法 它的定义如下
public interface Runnable {
public abstract void run();
}
Runnable的作用实现多线程,我们可以定义一个类A实现Runnable接口,然后通过new Thread(new A())等方式新建线程
Thread 是一个类,Thread本身就实现了Runnable接口 它的声明如下
public class ThreadTest implements Runnable {
@Override
public void run() {
}
}
Thread的作用实现多线程
Thread 和 Runnable的异同点
相同点:都是多线程的实现方式
不同点:Thread是类而Runnable是接口:Thread本身是实现了Runnable接口的类,我们知道"一个类只能有一个父类,但是却能实现多个接口"因此Runnable具有更好的扩展性 此外 Runnble还可以用于"资源的共享" 就是多个线程都是基于某一个Runnable对象建立的,他们会共享Runnable对象上的资源 通常我们是建议"Runnable"实现多线程
Thread和Runnable的多线程实例
1Thread的多线程实例
package com.tuhu.filt.javadata;
public class MyThread extends Thread{
private int ticket = 10;
public void run(){
for(int i =0;i < 20;i++){
if(this.ticket > 0){
System.out.println(
this.getName()
+ "卖票:ticket"
+this.ticket--
);
}
}
}
}
class TicketThreadTest{
public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
MyThread t3 = new MyThread();
t1.start();
t2.start();
t3.start();
}
}
MyThread继承于 Thread 他是自定义的线程,每个MyThread都会卖出10张票
主线程main创建并启动3个MyThread子线程 每个子线程都各自卖出了10张
其实这个不难理解 说是三个线程,其实三个线程每个都访问的是属于自己的那个对象,所以各自都会卖出10张票
2 Runnable的多线程示例
package com.tuhu.filt.javadata;
import java.lang.Runnable;
public class ThreadByRunnable implements Runnable{
private int ticket = 10;
@Override
public void run() {
for(int i = 0;i<20;i++){
if(this.ticket > 0){
System.out.println(
Thread.currentThread().getName()
+"卖票:ticket"
+this.ticket--
);
}
}
}
}
class RunnableTest{
public static void main(String[] args) {
/**
* 这个mt是共享的 看好了
*/
ThreadByRunnable mt = new ThreadByRunnable();
Thread t1 = new Thread(mt);
Thread t2 = new Thread(mt);
Thread t3 = new Thread(mt);
t1.start();
t2.start();
t3.start();
}
}
和上面的继承于Thread不同 这里的实现了Runable接口
主线程main 创建并启动了3个线程 而且着三个线程 都是基于"mt这个Runnable"对象而创建的,运行结果是这三个线程一共卖出了10张票,这说明了他们是共享Runnable接口的
我们下来比较下 单线程和多线程的执行时间
单线程
我们再来看看多线程的执行时间
我们可以看到
单线程的执行时间为 2
多线程的执行时间为 1
一般情况下 多线程肯定会比单线程快的,除非你建立很多无用的线程,增加了上下文切换的时间