java创建多线程的接口_java中创建多线程4种方式以及实现接口的优点

多线程创建方式有4种

创建线程的第一种方式。继承Thread类

1.继承Thread类

2.重写Thread类中的run方法--目的将自定义代码存储在run方法.让线程执行

3.调用线程的start()方法改方法有两个作用1启动线程 2让jvm调用run方法执行线程任务

创建线程的第二种方式。实现Runnable接口。

1,定义类实现Runnable接口:避免了继承Thread类的单继承局限性。

2,覆盖接口中的run方法。将线程任务代码定义到run方法中。

3,创建Thread类的对象:只有创建Thread类的对象才可以创建线程。

4,将Runnable接口的子类对象作为参数传递给Thread类的构造函数。

因为线程已被封装到Runnable接口的run方法中,而这个run方法所属于Runnable接口的子类对象,

所以将这个子类对象作为参数传递给Thread的构造函数,这样,线程对象创建时就可以明确要运行的线程的任务。

5,调用Thread类的start方法开启线程。

第二种方式实现Runnable接口避免了单继承的局限性,所以较为常用。

实现Runnable接口的方式,更加的符合面向对象,线程分为两部分,一部分线程对象,一部分线程任务。

继承Thread类:线程对象和线程任务耦合在一起。一旦创建Thread类的子类对象,既是线程对象,有又有线程任务。

实现runnable接口:将线程任务单独分离出来封装成对象,类型就是Runnable接口类型。

Runnable接口对线程对象和线程任务进行解耦。

//通过查看源码了解一下将runnable接口的子类对象作为参数传递给Thread构造函数的原因。

classThread{privateRunnable target;

Thread(Runnable target)

{this.target =target;

}public voidrun() {if (target != null) {

target.run();

}

}public voidstart()

{

run();

}

}

Runnable d= newDemo();

Thread t= newThread(d);

t.start();

class Demo implementsRunnable

{privateString name;

Demo(String name)

{this.name =name;

}//覆盖了接口Runnable中的run方法。

public voidrun()

{for(int x=1; x<=20; x++)

{

System.out.println("name="+name+"..."+Thread.currentThread().getName()+"..."+x);

}

}

}classThreadDemo2

{public static voidmain(String[] args)

{//创建Runnable子类的对象。注意它并不是线程对象。

Demo d = new Demo("Demo");//创建Thread类的对象,将Runnable接口的子类对象作为参数传递给Thread类的构造函数。

Thread t1 = newThread(d);

Thread t2= newThread(d);//将线程启动。

t1.start();

t2.start();

System.out.println(Thread.currentThread().getName()+"----->");

}

}

第三种方式:

* 实现 Runnable

* 实现Callable

* 它俩区别:Runnable run方法没有返回值

* Callable call方法有返回值

* 创建线程第三种方式:实现Callable接口

* new Thread() api构造方法中没有直接传递Callable接口的 只有传Runnable

* 思考是不是有一个桥梁 将Callable和Runnable它俩联系起来的

* 这个桥梁就是FutureTask

*

* FutureTask 构造中传递的是Callable接口, 间接实现Runnable接口

* 因为FutureTask间接实现Runnable接口所以可以传递到new Thread()构造方法中

class MyThread implements Callable{

@Overridepublic Integer call() throwsException {

System.out.println(Thread.currentThread().getName()+"**************come in Callable");return 1024;

}

}public classCallableDemo {public static void main(String[] args) throwsInterruptedException, ExecutionException {

FutureTask task = new FutureTask<>(newMyThread());new Thread(task, "AA").start();//new Thread(task, "BB").start();//多个线程抢一个task,只会执行一次,想要执行多次起多个FutureTask

int result01 = 100;int result02 = task.get(); //建议放到最后,否则会造成阻塞//System.out.println("******result:"+task.get());

System.out.println("******result:"+(result01+result02));

}

}

第4种方式:线程池

/*** 生产环境 都是自定义线程池

*

* 合理配置线程池 如何考虑

*

* CPU密集型 公式 :cpu核数+1

* IO密集型 公式:cpu核数/1-阻塞系数 阻塞系数在0.8-0.9之间

* 比如:8核CPU: 8/1-0.9=80个线程数

*

* Runtime.getRuntime().availableProcessors() 得到CPU核数

*

自定义线程从池7个参数说明

核心线程数, 阻塞队列,最大线程数,拒绝策略, 其他线程空闲销毁时间,空闲时间单位,线程池工厂

*

*@authorwg

**/

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

System.out.println(Runtime.getRuntime().availableProcessors());

ExecutorService threadPool= newThreadPoolExecutor(2,5,1L,

TimeUnit.SECONDS,new LinkedBlockingQueue<>(3),

Executors.defaultThreadFactory(),//new ThreadPoolExecutor.AbortPolicy() 超过极限8就报异常//new ThreadPoolExecutor.CallerRunsPolicy()//测试10 超过的处理不过来的回退到调用者//new ThreadPoolExecutor.DiscardOldestPolicy()//测试10

newThreadPoolExecutor.DiscardPolicy()

);try{//模拟10个用户来办理业务,每个用户就是一个来自外部的请求线程

for (int i = 1; i <= 10; i++) {

threadPool.execute(()->{

System.out.println(Thread.currentThread().getName()+"\t 办理业务");

});

}

}catch(Exception e) {

e.printStackTrace();

}finally{

threadPool.shutdown();

}

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值