1. Thread
public class ThreadTest {
public static void main(String[] args){
new MyThread().start();
new MyThread().start();
}
}
class MyThread extends Thread{
int ticket=3;
@Override
public void run(){
for(int i=0;i<10;i++){
if(ticket>0){
System.out.println("售出车票第" + ticket-- + "张");
}
}
}
}
输出结果
售出车票第3张
售出车票第3张
售出车票第2张
售出车票第2张
售出车票第1张
售出车票第1张
每个Thread是一个独立线程,资源不共享
2. Runnable
public class RunnableTest {
public static void main(String[] args){
RunnableDemo runnable=new RunnableDemo();
new Thread(runnable,"售票线程1").start();
new Thread(runnable,"售票线程2").start();
}
}
class RunnableDemo implements Runnable{
private int ticket = 3;
@Override
public void run(){
System.out.println("当前线程名:" + Thread.currentThread().getName());
for (int i = 0; i < 10; i++) {
if(ticket>0) {
System.out.println("售出车票第" + ticket-- + "张");
}
}
}
}
输出结果
当前线程名:售票线程2
售出车票第3张
售出车票第2张
当前线程名:售票线程1
售出车票第1张
线程的真实执行顺序与代码顺序无关
3. Callable
public class CallableTest {
public static void main(String[] args) {
CallableDemo demo=new CallableDemo();
FutureTask<Integer> futureTask = new FutureTask<>(demo);
new Thread(futureTask, "callable线程").start();
try {
System.out.println("返回值:" + futureTask.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class CallableDemo implements Callable<Integer>{
@Override
public Integer call() throws Exception{
System.out.println("当前线程名:"+Thread.currentThread().getName());
int i=0;
for (; i < 5; i++) {
System.out.println("i="+i);
}
return i;
}
}
运行结果
当前线程名:callable线程
i=0
i=1
i=2
i=3
i=4
返回值:5
通过futureTask.get()获取线程返回值
对比
Runnable比Thread有下列优势
- 避免了Java单继承的特性
- 增强程序简装行,代码能被多个线程共享,代码与数据是独立的
- 适合多个相同程序代码的线程处理同一资源的情况
Runnable与Callable区别
- Callable.call(),Runnable.run()
- Callable执行后可返回值
- Callable可抛出异常
- 运行Callable任务可以拿到一个Future队形,表示异步计算的结果。通过Future可了解任务执行情况,可取消任务的执行,还可以获取执行结果
- 加入线程池运行,Runable使用execute,Callable使用submit方法