标签:getname sel 进入 优先级 this 直接 总结 ack executor
Java实现多线程有四种方式:
1.继承Thread类;
2.实现Runable接口;
3.实现Callable接口,通过FutureTask包装器来创建Thread线程;
4.使用ExecutorService、Callable、Future实现有返回结果的多线程;
其中前两种线程执行完是没有返回结果的,后两种是有返回值的。
先贴出一个多线程售票的简单示例,根据代码去理解多线程:
/** * 一个售票类,实现Runnable接口重写run()方法来实现线程 */ @Data public class SellTicket implements Runnable{ //票总数 private int tickets; SellTicket(int tickets){ this.tickets = tickets; } @Override public void run() { while(true) { //锁,如果这里不加锁的话,当多个线程同时进入tickets > 0时,可能会出现最后余票为-1,-2的情况 synchronized (this){ if(tickets > 0) { try { Thread.sleep(100); } catch(Exception e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖掉一张票,剩下: " + --tickets +"张"); }else{ break; } } } } }
/** * 测试类 */ public class Test { public static void main(String[] args) { SellTicket p1 = new SellTicket(20); Thread t1 = new Thread(p1,"线程1"); Thread t2 = new Thread(p1,"线程2"); Thread t3 = new Thread(p1,"线程3"); //setPriority(),参数为1-10,参数越大,优先级越高,参数超过10会报错 //t1.setPriority(1); //t2.setPriority(2); //t3.setPriority(10); t1.start(); t2.start(); t3.start(); } }
运行结果:
在测试类中,如果将注释的优先级放开,那执行结果都会是线程3在售票,当票数更多时,线程1和线程2也会开始售票。当有优先调度需求时,setPriority()就能派上用场。
总结:
1. 前两种创建多线程的方式差不多,只是因为Java只支持单继承但可以实现多个接口,所以继承Thread类来实现接口会有一定的局限性。
2.Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。
3.
标签:getname sel 进入 优先级 this 直接 总结 ack executor
原文地址:https://www.cnblogs.com/tryCatch-lcc/p/11994009.html