标签:线程
启动:创建子类对象+对象.start()
缺点:Java只支持单继承,如果我们的类已经从一个类继承,则无法再继承Thread类。
package Thread;
/**
* 模拟龟兔赛跑
* 1、创建多线程(方式一):继承 Thread + 重写run方法(线程体)
* 2、使用线程:创建子类对象 + 对象.start()方法 线程启动
*/
public class Demo01 {
public static void main(String[] args) {
//创建子类对象
Rabbit rab = new Rabbit();
Tortoise tor = new Tortoise();
//调用start方法 ,启动线程。 内部由CPU管控
rab.start(); //不要调用run方法,由内部自己调用。
tor.start();
for(int i=0;i<30;i++)
{
System.out.println("main-->"+i);
}
}
}
class Rabbit extends Thread{
//线程体 一切从run开始
@Override
public void run() {
//线程体
for(int i=0;i<30;i++)
{
System.out.println("兔子跑了"+i+"步");
}
}
}
class Tortoise extends Thread
{
@Override
public void run() {
//线程体
for(int i=0;i<30;i++)
{
System.out.println("乌龟跑了"+i+"步");
}
}
}
启动:使用静态代理
1)、创建真实角色
2)、创建代理角色
3)、调用start()方法 启动线程
优点:可以同时实现继承,Runnable接口方式更加通用一些。
1、避免单继承的局限性
2、便于共享资源
通过实现Runnable接口实现多线程。(用到了静态代理设计模式)
http://blog.csdn.net/scgaliguodong123_/article/details/44025531
package Thread;
/**
* 推荐使用Runnable创建线程
* 1、避免单继承的局限性
* 2、便于共享资源
*/
public class Demo03 {
public static void main(String[] args) {
//1)、创建真实角色
Programmer pro = new Programmer();
//2)、创建代理角色+真实角色引用
Thread proxy = new Thread(pro);
//3)、调用start()方法 启动线程
proxy.start();
for(int i=0;i<100;i++){
System.out.println("一边聊QQ");
}
}
}
/**
* 使用Runnable 创建进程
* 1、类实现Runable接口+重写run()方法
* 2、启动多线程 使用静态代理
* 1)、创建真实角色
* 2)、创建代理角色
* 3)、调用start()方法 启动线程
*/
class Programmer implements Runnable{
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println("一边敲代码");
}
}
}
package Thread;
/**
* 抢票系统
* 方便共享资源
*/
public class Demo04 implements Runnable{
private int num = 50;
@Override
public void run() {
while(true){
if(num<=0)
{
break;//跳出循环
}
System.out.println(Thread.currentThread().getName()+"抢到了倒数第"+num--+"张。");
}
}
public static void main(String[] args) {
//真实角色
Demo04 web = new Demo04();
//代理
Thread t1 = new Thread(web,"德玛西亚");
Thread t2 = new Thread(web,"卡特琳娜");
Thread t3 = new Thread(web,"德邦总管");
//启动线程
t1.start();
t2.start();
t3.start();
}
}
Callable 和 Future接口
Callable是类似于Runnable的接口,实现*Callable接口的类和实现Runnable的类都是可被其它线程执行的任务*。
优点:可以返回值,可以抛异常。
缺点:实现繁琐。
步骤:
1、实现Callable接口+重写call方法
2、借助执行调度服务ExecutorService
获取Future
对象
ExecutorService ser = Executors.newFixedThreadPool(2);
Future<Integer> result= ser.submit(tortoise);
3、获取值result
int num = result.get();
get方法返回值是一个泛型
4、停止服务ser.shutdownNow();
package Thread;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* 使用Callable接口方式创建多线程
*/
public class Demo05 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//1、创建线程
ExecutorService ser = Executors.newFixedThreadPool(2);//开两个线程
Race tortoise = new Race("老乌龟",1000);
Race rabbit = new Race("小兔子",500);
//2、获取Future对象
Future<Integer> result1 = ser.submit(tortoise);
Future<Integer> result2 = ser.submit(rabbit);
Thread.sleep(2000);//2秒
tortoise.setFlag(false);//停止线程体循环 设置flag = false;
rabbit.setFlag(false);
//3、获取值
int num1 = result1.get();
int num2 = result2.get();
System.out.println("乌龟跑了-->"+num1+"步");
System.out.println("兔子跑了-->"+num2+"步");
//4、停止服务
ser.shutdownNow();
}
}
class Race implements Callable<Integer>
{
private String name;//名称
private long time;//延时时间
private boolean flag = true;
private int step = 0;//步
public Race() {
}
public Race(String name) {
super();
this.name = name;
}
public Race(String name, int time) {
super();
this.name = name;
this.time = time;
}
//有返回值了
@Override
public Integer call() throws Exception {
while(flag){
Thread.sleep(time);//延时
step++;
}
return step;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
}
运行结果:
乌龟跑了-->3步
兔子跑了-->5步
(1)Callable规定的方法是call(),而Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
(3)call()方法可抛出异常,而run()方法是不能抛出异常的。
(4)运行Callable任务可拿到一个Future对象,Future表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。
标签:线程
原文地址:http://blog.csdn.net/scgaliguodong123_/article/details/46013283