java多线程操作ui_Java多线程 - osc_11ine1ui的个人空间 - OSCHINA - 中文开源技术交流社区...

Java多线程

Java实现多线程有四种方式:

1.继承Thread类;

2.实现Runable接口;

3.实现Callable接口,通过FutureTask包装器来创建Thread线程;

4.使用ExecutorService、Callable、Future实现有返回结果的多线程;

其中前两种线程执行完是没有返回结果的,后两种是有返回值的。

先贴出一个多线程售票的简单示例,根据代码去理解多线程:

/*** 一个售票类,实现Runnable接口重写run()方法来实现线程*/@Datapublic class SellTicket implementsRunnable{//票总数

private inttickets;

SellTicket(inttickets){this.tickets =tickets;

}

@Overridepublic voidrun() {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 classTest {public static voidmain(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();

}

}

运行结果:

2f7b87dd4a6ae88a98099e693ff3b748.png

在测试类中,如果将注释的优先级放开,那执行结果都会是线程3在售票,当票数更多时,线程1和线程2也会开始售票。当有优先调度需求时,setPriority()就能派上用场。

总结:

1. 前两种创建多线程的方式差不多,只是因为Java只支持单继承但可以实现多个接口,所以继承Thread类来实现接口会有一定的局限性。

2.Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。

修改售票示例,通过实现Callable接口实现多线程,并知道线程2卖了多少张票:

/*** 一个售票类,实现Callable接口重写call()方法来实现线程*/@Datapublic class SellTickets implements Callable{//票总数

private inttickets;

SellTickets(inttickets){this.tickets =tickets;

}

@OverridepublicInteger call() {int thread2 = 0;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 +"张");if("Thread-1".equals(Thread.currentThread().getName())){

thread2++;

}

}else{break;

}

}

}returnthread2;

}

}

/*** 测试类*/

public classTest {public static voidmain(String[] args) {

Callable callable = new SellTickets(100);

FutureTask futureTask = new FutureTask<>(callable);

Thread thread= newThread(futureTask);

thread.start();

FutureTask futureTask2 = new FutureTask<>(callable);

Thread thread2= newThread(futureTask2);

thread2.start();//获取线程2的返回值

Integer sum = 0;try{

sum=futureTask2.get();

}catch(Exception e){

e.printStackTrace();

}

System.out.println("线程2售票:"+sum+"张");

}

}

1312c43f6a8510b3ce333c0400fdcbf2.png

具体是创建Callable接口的实现类,并实现call()方法。并使用FutureTask类来包装Callable实现类的对象,且以此FutureTask对象作为Thread对象的target来创建线程。首先,我们发现,在实现Callable接口中,此时不再是run()方法了,而是call()方法,此call()方法作为线程执行体,同时还具有返回值!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值