java8 实例请移步https://www.cnblogs.com/ngLee/p/14021859.html

进程与线程

进程是所有线程的集合,每一个线程是进程中的一条执行路径。

多线程的创建方式,继承Thread\实现Runable

/**

* 第一种创建线程的方式,继承Thread

*/

public class MultiThread extends Thread{

@Override

public void run() {

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

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

}

}

}

/**

* 第二种,实现Runnable接口,更易于扩展。(多实现,单继承)

*/

public class MultiThread2 implements Runnable {

@Override

public void run() {

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

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

}

}

}

/**

* 测试类

*/

public class TestThread {

public static void main(String[] args) {

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

//1.多线程创建 继承Thread

MultiThread multiThread = new MultiThread();

Thread thread = new Thread(multiThread,"线程继承Thread-1");

Thread thread2 = new Thread(multiThread,"线程继承Thread-2");

//2.启动多线程调用的是start(),而不是run()

thread.start();

thread2.start();

//3.打印效果 当前线程:线程1

/**********************************/

//2 实现Runnable

Runnable runnable = new MultiThread2();

Thread thread3 = new Thread(runnable,"线程实现Runnable-1");

Thread thread4 = new Thread(runnable,"线程实现Runnable-2");

thread3.start();

thread4.start();

//3 匿名内部类的方式

Thread thread5 = new Thread(new Runnable() {

@Override

public void run() {

for (int i = 0; i < 3; i++) {

System.out.println(Thread.currentThread().getName()+"匿名内部类----"+i);

}

}

});

thread5.start();

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

}

}

效果展示:并不是按照自上而下的执行

线程的几个状态

新建状态:当用new操作符创建一个线程时, 例如new Thread(r),线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码。

就绪状态:一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。处于就绪状态的线程并不一定立即运行run()方法,线程还必须同其他线程竞争CPU时间,只有获得CPU时间才可以运行线程。因为在单CPU的计算机系统中,不可能同时运行多个线程,一个时刻仅有一个线程处于运行状态。因此此时可能有多个线程处于就绪状态。对多个处于就绪状态的线程是由Java运行时系统的线程调度程序(thread scheduler)来调度的。

运行状态:当线程获得CPU时间后,它才进入运行状态,真正开始执行run()方法。

阻塞状态: 线程运行过程中,可能由于各种原因进入阻塞状态:

1>线程通过调用sleep方法进入睡眠状态;

2>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;

3>线程试图得到一个锁,而该锁正被其他线程持有;

4>线程在等待某个触发条件;

死亡状态:有两个原因会导致线程死亡:1)run方法正常退出而自然死亡,2)一个未捕获的异常终止了run方法而使线程猝死。为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法。如果是可运行或被阻塞,这个方法返回true; 如果线程仍旧是new状态且不是可运行的, 或者线程死亡了,则返回false.

简单需求:目前蚂蚁课堂有10万个用户,现在蚂蚁课堂需要做活动,给每一个用户发送一条祝福短信

/**

* 提交实体

*/

public class UserThread extends Thread {

private List uList;

public UserThread(List uList){

this.uList = uList;

}

public List getuList() {

return uList;

}

public void setuList(List uList) {

this.uList = uList;

}

@Override

public void run() {

uList.stream().forEach(userEntity -> {

System.out.println("threadName:" + Thread.currentThread().getName() + "-用户记录序号:" + userEntity.getUno()

+ "---用户名称:" + userEntity.getUname());

//短信发送接口

});

}

}

/**

* 测试类

*/

public class TestThread {

public static void main(String[] args) {

//所有记录

List list = new ArrayList<>();

for (int i = 0; i < 100; i++) {

UserEntity userEntity = new UserEntity();

userEntity.setUno("用户id"+i);

userEntity.setUname("用户名字"+i);

list.add(userEntity);

}

//将数据进行分割,每组四千,这个每组数据量最好取配置,使用高峰期调低,保证不会超时

int everyNum = 20;

List> lists= spiltList(list,everyNum);

for (int i = 0; i < lists.size(); i++) {

Thread th = new UserThread(lists.get(i));

th.start();

}

//第二种java8 并行流,底层:ForkJoin --todo

//使用并行流的时候,最好不要修改数据,如果需要map里的返回值,则用Collectors进行收集,不要foreach里用list.add()

lists.parallelStream().forEach( lst -> {

lst.parallelStream().forEach( userEntity -> {

System.out.println("threadName:" + Thread.currentThread().getName() + "-用户记录序号:" + userEntity.getUno()

+ "---用户名称:" + userEntity.getUname());

});

});

}

private static List> spiltList(List list, int everyNum) {

//总数据量

int total = list.size();

//分组数量

int group = total%everyNum == 0 ? total/everyNum : total/everyNum +1 ;

//java8 stream

List userList = Stream.iterate(0, n->n+1).

limit(group).parallel().

map(seed -> {

List list1 = list.stream().skip(seed * everyNum).limit(everyNum).

collect(Collectors.toList());

return list1;

}

).collect(ArrayList::new,ArrayList::add,List::addAll);

return userList;

}

}

打印效果如图,不是按顺序打印,但这不正好就是多线程需要的效果的了吗?

java并行流 阻塞主线程_多线程入门案例与java8的并行流相关推荐

  1. java并行流 阻塞主线程_记一次使用Java8并行流导致的服务瓶颈问题排查

    一.业务背景# 二.服务架构# 服务使用线程池对请求进行业务处理,corePoolSize=32,maximumPoolSize=128. 三.问题描述# 服务部署到测试环境,将线上流量通过tcp-c ...

  2. java foreach多线程_详解多线程入门案例与java8的并行流

    进程与线程 进程是所有线程的集合,每一个线程是进程中的一条执行路径. 多线程的创建方式,继承Thread实现Runable /*** 第一种创建线程的方式,继承Thread*/ public clas ...

  3. 模态对话框阻塞主线程的话不影响其他线程操作主线程控件(不阻塞)

    Task.Factory.StartNew(() => {Thread.Sleep(5000);this.Invoke(new Action(() => {this.button7.Tex ...

  4. 4.5.2.5_主线程_墨镜滤镜

    4.5.2.5_主线程_墨镜滤镜 <!DOCTYPE html> <html><head><meta charset="UTF-8"> ...

  5. java的main是主线程吗_main函数是主线程吗

    1.线程的概念: 线程是程序最基本的运行单位,而进程不能运行,所以能运行的,是进程中的线程. 2.线程是如何创建起来的: 进程仅仅是一个容器,包含了线程运行中所需要的数据结构等信息.一个进程创建时,操 ...

  6. android判断主线程_惊天秘密!从Thread开始,揭露Android线程通讯的诡计和主线程的阴谋...

    背景介绍 我们在Android开发过程中,几乎都离不开线程.但是你对线程的了解有多少呢?它完美运行的背后,究竟隐藏了多少不为人知的秘密呢?线程间互通暗语,传递信息究竟是如何做到的呢?Looper.Ha ...

  7. 【Java并发编程】主线程等待子线程的多种方法

    文章目录 1.Thread sleep() 2.Thread join() 3.synchronized 等待唤醒机制 4.ExecutorService isTerminated() + while ...

  8. python如何强制结束主线程_强制结束线程

    场景: 如果某个线程持续阻塞,无法退出,从而导致整个程序无法结束,此时就需要强制结束线程 思路:由于程序阻塞,比如卡在代码中的某一行后,一直无法向下执行,此时,无法通过常规方式结束线程 方法1: 采用 ...

  9. java中子线程与主线程通信_Android笔记(三十二) Android中线程之间的通信(四)主线程给子线程发送消息...

    之前的例子都是我们在子线程(WorkerThread)当中处理并发送消息,然后在主线程(UI线程)中获取消息并修改UI,那么可以不可以在由主线程发送消息,子线程接收呢?我们按照之前的思路写一下代码: ...

最新文章

  1. 阿里二面,原来我对自动化测试的理解太浅了
  2. outlook2007 未知错误,代码0x80040600解决方法
  3. 降低网站跳出率的技巧分享!
  4. SDNU 1330.Max Sum(最大子序列和)
  5. 微信小程序实现时间戳转为时间格式
  6. [转]游戏UI与flash 组件开发
  7. html画图代码_python之matplotlib画图教程(1)
  8. 第九届中国开源黑客松活动将于2019年4月18日-4月20日,在深圳举办
  9. C语言杨辉三角形代码
  10. shell教程(4)变量(二):字符串变量截取、替换和删除
  11. lumion鸟瞰图---制作心得
  12. SQL Leetcode练习题
  13. Android流量统计
  14. mysql写周报_mysql 数据分析如何实现日报、周报、月报和年报?
  15. 笔记本怎么做wifi热点(xp版)
  16. 独家报道|配音工具大放送|这么好听的声音居然……(教程篇)
  17. 数据结构2(线性表)
  18. 使用SpannableString实现一个load小动画
  19. hp激光打印出来字淡的处理方法
  20. 线程安全、volatile关键字、原子性、并发包、死锁、线程池

热门文章

  1. 产品开发管理之流程和体系(总篇)
  2. 为什么我们要使用Async、Await关键字
  3. 微软发布ReactXP:方便开发者构建跨平台应用
  4. docker – 你应该知道的10件事
  5. PS2019摄影后期处理(二)
  6. PHP使用for循环打出星号表格,console - JavaScript中,使用for循环输出如下图形(等腰三角形,和平行四边形)?原理是啥?...
  7. 【遥感数字图像处理】实验:遥感图像分析方法大全(Erdas版)
  8. C和指针之多维数组一行存满后会轮到下一行
  9. node.js npm常用命令
  10. windows下配置mysql主从复制_Windows下MySQL主从复制的配置方法