多线程创建方式有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构造函数的原因。
class Thread{ private Runnable target; Thread(Runnable target)
{
this.target = target;
}
public void run() {
if (target != null) {
target.run();
}
}
public void start()
{
run();
}
} Runnable d = new Demo();
Thread t = new Thread(d);
t.start();
class Demo implements Runnable
{
private String name;
Demo(String name)
{
this.name = name;
}
//覆盖了接口Runnable中的run方法。
public void run()
{
for(int x=1; x<=20; x++)
{
System.out.println("name="+name+"..."+Thread.currentThread().getName()+"..."+x);
}
}
} class ThreadDemo2
{
public static void main(String[] args)
{
//创建Runnable子类的对象。注意它并不是线程对象。
Demo d = new Demo("Demo");
//创建Thread类的对象,将Runnable接口的子类对象作为参数传递给Thread类的构造函数。
Thread t1 = new Thread(d);
Thread t2 = new Thread(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<Integer> {

    @Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName()+"**************come in Callable");
return 1024;
} }
public class CallableDemo { public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureTask<Integer> task = new FutureTask<>(new MyThread()); 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个参数说明
  核心线程数, 阻塞队列,最大线程数,拒绝策略, 其他线程空闲销毁时间,空闲时间单位,线程池工厂
*
* @author wg
*
*/
public class MyThreadPool {
public static void main(String[] args) {
System.out.println(Runtime.getRuntime().availableProcessors()); ExecutorService threadPool = new ThreadPoolExecutor(
2,
5,
1L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<>(3),
Executors.defaultThreadFactory(),
// new ThreadPoolExecutor.AbortPolicy() 超过极限8就报异常
// new ThreadPoolExecutor.CallerRunsPolicy() //测试10 超过的处理不过来的回退到调用者
// new ThreadPoolExecutor.DiscardOldestPolicy() //测试10
new ThreadPoolExecutor.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();
}
} }

java中创建多线程两种方式以及实现接口的优点的更多相关文章

  1. K:java中序列化的两种方式—Serializable或Externalizable

    在java中,对一个对象进行序列化操作,其有如下两种方式: 第一种: 通过实现java.io.Serializable接口,该接口是一个标志接口,其没有任何抽象方法需要进行重写,实现了Serializ ...

  2. Java线程创建的两种方式

    java多线程总结一:线程的两种创建方式及优劣比较 (一)---之创建线程的两种方式 java实现多线程的两种方法的比较

  3. 在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口

    //继承thread类 class PrimeThread extends Thread{ long minPrime; PrimeThread(long minPrime) { this.minPr ...

  4. Virsh中创建虚拟机两种方式define和create的区别

    本质上两者一样的,都是从xml配置文件创建虚拟机 define  丛xml配置文件创建主机但是不启动 create  同样是丛xml配置文件创建主机,但是可以指定很多选项,比如是否启动,是否连接控制台 ...

  5. 【转载】JAVA中线程的两种实现方法-实现Runnable接口和继承Thread类

    转自: http://blog.csdn.net/sunguangran/article/details/6069317 非常感谢原作者,整理的这么详细. 在java中可有两种方式实现多线程,一种是继 ...

  6. Java中创建对象的几种方式

    Java中创建对象的五种方式: 作为java开发者,我们每天创建很多对象,但是我们通常使用依赖注入的方式管理系统,比如:Spring去创建对象,然而这里有很多创建对象的方法:使用New关键字.使用Cl ...

  7. 对Java代码加密的两种方式,防止反编译

    使用Virbox Protector对Java项目加密有两种方式,一种是对War包加密,一种是对Jar包加密.Virbox Protector支持这两种文件格式加密,可以加密用于解析class文件的j ...

  8. Java中创建对象的五种方式

    我们总是讨论没有对象就去new一个对象,创建对象的方式在我这里变成了根深蒂固的new方式创建,但是其实创建对象的方式还是有很多种的,不单单有new方式创建对象,还有使用反射机制创建对象,使用clone ...

  9. 【转】Java中创建对象的5种方式

    Java中创建对象的5种方式   作为Java开发者,我们每天创建很多对象,但我们通常使用依赖管理系统,比如Spring去创建对象.然而这里有很多创建对象的方法,我们会在这篇文章中学到. Java中有 ...

随机推荐

  1. java 线程的死锁问题

    以下的情况可能出现死锁 1.一个对象的同步方法去调用另一个对象的同步方法,同时另一个对象的同步方法也在调用这个对象的同步方法,导致一定几率的死锁,不一定每次都会出现死锁,模拟的代码如下 package ...

  2. Python的多线程编程

    提到多线程,很多人就会望而却步,本文将由浅入深地带你攻克python多线程编程,并防止你跳入深坑, 首先看一段简单的代码: from time import ctime,sleep def play_ ...

  3. 2016-12-30 PHP JS

    1:Js 控制图片样式 2:PHP WEB

  4. Redis的安装与使用(单节点)

    IP:192.168.4.111 环境:CentOS 6.6 Redis版本:redis-3.0 (考虑到Redis3.0在集群和性能提升方面的特性,rc版为正式版的候选版,而且很快就出正式版) 安装 ...

  5. 【LeetCode】206. Reverse Linked List

    题目: Reverse a singly linked list. 提示: 此题不难,可以用迭代或者递归两种方法求解.记得要把原来的链表头的next置为NULL: 代码: 迭代: /** * Defi ...

  6. Redux-Saga学习心得

    # Redux Saga ## 简述- Reducers负责处理action的state更新:- Sagas负责协调那些复杂或异步的操作. ## 安装 npm install --save redux ...

  7. ifame高度自动适应子页面内容

    被这个问题折磨了好久,试了很多方法都不行,总算解决了,记录一下. <div class="iframe-pro" id="iframe-proid"> ...

  8. Vijos 1033 整数分解(版本2)

    描述 整数分解(版本2) 一个正整数可以分解成若干个自然数之和.请你编一个程序,对于给出的一个正整数n(1<=n<=1500),求出满足要求的分解方案,并使这些自然数的乘积m达到最大. 例 ...

  9. 利用powershell反弹shell到metasploit

    一.使用msfvenom生成PS1文件: msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST= -f psh-reflection >.p ...

  10. 我的学习之路_第三十章_servlet

    servlet:小服务程序 servlet是JavaWeb体系中的三大核心(servlet/Filter/Listener)之一,而且是最主要的那个. 作用:接受请求,处理请求,做出响应 继承体系:s ...