一 创建线程的三种方式
1、Thread方式
/**
* 多线程创建的方式1
* 1. 创建Thread的子类
* 2. 重写run方法 [业务执行体-逻辑主要存在的地方]
* 3. 创建子类的示例.start启动
*/
public class ThreadCreateMethodOne extends Thread {
/**
* 继承Thread方式定义的线程,要将变量定义成static 类变量资源才能被共享
*/
public static int i = 100;
public static Object obj = new Object();
@Override
public void run() {
while (i > 0) {
synchronized (obj) {
try {
i--;
System.out.println(this.getName() + (i > 0 ? (": 余票 " + i + " 张") : (": 已售完")));
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
2、Runnable 方式
/**
* 线程创建的方式2
* 1. 实现Runnable
* 2. 重写run方法
* 3. 创建实例
* 4. 将实例作为参数传递给new Thread(Runnable runnable, String name)
* 5. start 启动
*
*/
public class ThreadCreateMethodSecond implements Runnable {
int i =100;
Object obj = new Object();
@Override
public void run() {
while (i > 0) {
synchronized (obj) {
try {
i--;
System.out.println(Thread.currentThread().getName() + (i > 0 ? (": 余票 " + i + " 张") : (": 已售完")));
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
final ThreadCreateMethodSecond th1 = new ThreadCreateMethodSecond();
new Thread(th1,"窗口1").start();
new Thread(th1,"窗口2").start();
}
}
3、Callable 方式
/**
* 线程创建的方式3
* 1. 实现Callable
* 2. 重写call方法 有返回值
* 3. 创建Callable 子类的实例
* 4. 将Callable 子类的实例传递给 new FutureTask(Callable)
* 5. 将FutureTask 实例作为参数传给 new Thread(FutureTask task,String name)
* 6. start 启动
*/
public class ThreadCreateMethodThree implements Callable<Integer> {
int i =100;
@Override
public Integer call() {
while (i > 0) {
try {
i--;
System.out.println(Thread.currentThread().getName() + (i > 0 ? (": 余票 " + i + " 张") : (": 已售完")));
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return i;
}
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
final FutureTask<Integer> task = new FutureTask<>(new ThreadCreateMethodThree());
new Thread(task,"窗口1").start();
System.out.println("返回值---------------------"+task.get());
}
}
二、三种线程对比
上述3种方式都可以实现多线程,存在即合理;
-
Runnable 和 callable方式:[推荐]
- 优点
- 线程类在实现Runnable/callable的前提下还可以去继承其他类.更加面向对象
- Callable 是JDK1.5版本出来的.JDK1.8加强[Lamdba/函数式接口],Runbale JDK1.8也支持函数式编程
- Runable和Callable更加适合处理共享资源的情况
- 劣势
- 编程稍稍麻烦一下.而且获取当前线程需要使用Thread类的静态方法currentThread()方法
- 优点
-
Thread 方式
- 优点
- 编程简单.可以直接获取当前线程
- 劣势
- java单继承.无法继承其他类.有局限性
- 优点
本文参考 <<疯狂java第三版>> 16章节