文档目录:

一、进程与线程

二、多线程的实现

三、获取线程名与线程对象

四、线程sleep方法

五、线程调度与优先级

六、线程安全(重点)

七、死锁

---------------------------------------分割线:正文--------------------------------------------------------

一、进程与线程

1、基本概念

进程是一个应用程序。

线程是一个进程中的执行场景/执行单元。

一个进程可以启动多个线程

2、举例说明进程与线程、

java输出helloworld回车,先启动JVM是一个进行,JVM再启动一个主线程调用main方法,同时再启动一个垃圾回收线程负责看护,回收垃圾,至少两个线程并发。

3、进程与线程的关系

阿里巴巴:进程A

马云:阿里巴巴的一个线程

张小龙:阿里巴巴的一个线程

京东:进程B

强东:jd的一个线程

奶茶:jd的一个吸纳还曾

进程A与B内存独立不共享(阿里与jd资源不共享)

线程A与线程B:JAVA中堆内存与方法区内存共享,栈内存独立

4、多线程机制的目的

提高程序的处理效率

二、多线程的实现

1、第一种实现方式:继承java.lang.Thread方法,并重新run方法

 1 package JAVAADVANCE;
2 public class TestAdvance37TestThread01 {
3 //这里是main方法,这里的代码属于主线程,在主线程中运行
4 public static void main(String[] args) {
5 //新建一个分支线程对象,
6 MyThread myThread=new MyThread();
7 //start开启新的栈空间,启动一个分支线程,启动成功线程自动调用run方法,而直接调用MyThread.run()不会启动多线程
8 myThread.start();
9 //这里的代码运行在主线程中
10 for (int i=0;i<100;i++){
11 System.out.println("主线程------->"+i);
12 }
13 }
14 }
15 class MyThread extends Thread{
16 @Override
17 public void run() {
18 //编写程序,这段代码在分支线程中执行
19 for(int i=0;i<100;i++){
20 System.out.println("分支线程------->"+i);
21 }
22 }
23 }

查看执行结果片段:主线程与分支线程是并发的

1 主线程------->91
2 主线程------->92
3 分支线程------->0
4 主线程------->93
5 分支线程------->1
6 主线程------->94
7 主线程------->95

2、第二种实现方式:编写一个类,实现java.lang.Runnable接口,实现run方法(建议使用,因为此类还可以继承其他方法)

 1 package JAVAADVANCE;
2
3 public class TestAdvance37TestThread02 {
4 public static void main(String[] args) {
5 //创建线程对象,将可运行的对象封装成线程对象
6 Thread t = new Thread(new MyRunnable());
7 t.start();
8 //这里的代码运行在主线程中
9 for (int i = 0; i < 100; i++) {
10 System.out.println("主线程------->" + i);
11 }
12 }
13 }
14 class MyRunnable implements Runnable{
15 @Override
16 public void run() {
17 for(int i=0;i<100;i++){
18 System.out.println("分支线程------->"+i);
19 }
20 }
21 }

查看执行结果片段:主线程与分支线程是并发的

1 分支线程------->54
2 主线程------->4
3 主线程------->5
4 分支线程------->55
5 主线程------->6
6 主线程------->7

3、第三种实现方式:采用匿名内部类方法

 1 package JAVAADVANCE;
2
3 public class TestAdvance37TestThread03 {
4 public static void main(String[] args) {
5 Thread t = new Thread(new Runnable() {
6 @Override
7 public void run() {
8 for (int i = 0; i < 100; i++) {
9 System.out.println("分支线程------->" + i);
10 }
11 }
12 });
13 //启动分支线程
14 t.start();
15 for (int i = 0; i < 100; i++) {
16 System.out.println("主线程------->" + i);
17 }
18 }
19 }

查看执行结果片段:主线程与分支线程是并发的

1 分支线程------->10
2 主线程------->12
3 分支线程------->11
4 主线程------->13
5 分支线程------->12
6 主线程------->14
7 分支线程------->13

4、第四种实现方式:实现callable接口(JDK8新特性)

(1)优先与缺点:

优点:可以拿到线程的执行结果

缺点:效率比较低,获取结果时,当前线程受阻塞

(2)实现方式

 1 package JAVAADVANCE;
2
3 import java.util.concurrent.Callable;
4 import java.util.concurrent.ExecutionException;
5 import java.util.concurrent.Future;
6 import java.util.concurrent.FutureTask;
7
8 public class TestAdvance37TestThread10 {
9 public static void main(String[] args) {
10 //创建一个未来任务对象,需要黑一个callable接口实现类的对象,这里使用匿名内部类
11 FutureTask task=new FutureTask(new Callable() {
12 @Override
13 public Object call() throws Exception {
14 //call()类似run方法,但是有返回值
15 //模拟行为
16 System.out.println("call method begin");
17 Thread.sleep(1000*10);
18 System.out.println("call method end");
19 int a=100;
20 int b=200;
21 return a+b; //自动装箱,300结果变为Integer
22 }
23 });
24 //创建线程对象
25 Thread t=new Thread(task);
26 //启动线程
27 t.start();
28 //获取t线程的返回结果
29 try {
30 Object obj=task.get();
31 System.out.println("线程的执行结果为:"+obj);
32 } catch (InterruptedException e) {
33 e.printStackTrace();
34 } catch (ExecutionException e) {
35 e.printStackTrace();
36 }
37 //main方法这里的程序要想执行必须等待get方法
38 System.out.println("hello world");
39
40 }
41 }

查看执行结果:hello world在10秒后展示

call method begin
call method end
线程的执行结果为:300
hello world

三、获取线程名与线程对象

 1 package JAVAADVANCE;
2
3 public class TestAdvance37TestThread04 {
4 public static void main(String[] args) {
5 //获取当前线程对象
6 Thread t1=Thread.currentThread();
7 System.out.println("main方法下的当前线程名:"+t1.getName());
8 MyThread t2=new MyThread();
9 //查看线程默认名
10 System.out.println("线程默认名:"+t2.getName());
11 t2.setName("ttttt");
12 System.out.println("修改后的线程名:"+t2.getName());
13 }
14 }

查看执行结果

main方法下的当前线程名:main
线程默认名:Thread-0
修改后的线程名:ttttt

四、线程sleep方法

1、概念:

(1)sleep为静态方法

(2)参数为毫秒

(3)作用:让当前线程进入休眠,进入"阻塞状态",放弃占用cpu时间片,让给其他线程使用

2、举例说明sleep方法

 1 package JAVAADVANCE;
2
3 public class TestAdvance37TestThread05 {
4 public static void main(String[] args) {
5 //让当前进程进入休眠状态,睡眠5秒
6 try {
7 Thread.sleep(1000*5);
8 System.out.println("hello world");
9 } catch (InterruptedException e) {
10 e.printStackTrace();
11 }
12 }
13 }

5秒后控制台打印hello world

3、中止进程的睡眠

注:run()方法内只能try catch,不能throws,因为子类不能比父类抛出更多的异常

 1 package JAVAADVANCE;
2
3 public class TestAdvance37TestThread06 {
4 public static void main(String[] args) {
5 Thread t=new Thread(new MyRunnable2());
6 t.setName("t");
7 t.start();
8 try {
9 Thread.sleep(1000*5);
10 } catch (InterruptedException e) {
11 e.printStackTrace();
12 }
13 //终于线程的睡眠
14 t.interrupt();
15 }
16 }
17
18 class MyRunnable2 implements Runnable{
19 @Override
20 public void run() {
21 System.out.println(Thread.currentThread().getName()+"---->begin");
22 try {
23 Thread.sleep(1000*60*60*24*365);
24 } catch (InterruptedException e) {
25 e.printStackTrace();
26 }
27 System.out.println(Thread.currentThread().getName()+"----->end");
28 }
29 }

查看运行结果:sleep5秒后出现异常信息,进程被中止

t---->begin
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at JAVAADVANCE.MyRunnable2.run(TestAdvance37TestThread06.java:23)
at java.lang.Thread.run(Thread.java:748)
t----->end Process finished with exit code 0

4、强行终止进程执行

 1 package JAVAADVANCE;
2
3 public class TestAdvance37TestThread07 {
4 public static void main(String[] args) {
5 Thread t=new Thread(new MyRunnable3());
6 t.setName("t");
7 t.start();
8 try {
9 Thread.sleep(1000*5);
10 } catch (InterruptedException e) {
11 e.printStackTrace();
12 }
13 t.stop();
14 }
15 }
16
17 class MyRunnable3 implements Runnable{
18 @Override
19 public void run() {
20 for(int i=0;i<10;i++){
21 System.out.println(Thread.currentThread().getName()+"------>"+i);
22 try {
23 Thread.sleep(1000);
24 } catch (InterruptedException e) {
25 e.printStackTrace();
26 }
27 }
28 }
29 }

stop方法的缺点:容易丢失数据,直接将线程杀死

5、合理的终止一个线程的执行

 1 package JAVAADVANCE;
2
3 import static java.lang.Thread.sleep;
4
5 public class TestAdvance37TestThread08 {
6 public static void main(String[] args) {
7 MyRunnable4 r=new MyRunnable4();
8 Thread t=new Thread(r);
9 t.setName("t");
10 t.start();
11 try {
12 sleep(1000*5);
13 } catch (InterruptedException e) {
14 e.printStackTrace();
15 }
16 //什么时候中止t改为false
17 r.run=false;
18 }
19 }
20
21 class MyRunnable4 implements Runnable{
22 //打一个布尔标记
23 boolean run=true;
24 @Override
25 public void run() {
26
27 for(int i=0;i<10;i++){
28 if(run){
29 System.out.println(Thread.currentThread().getName()+"----->"+i);
30 try {
31 sleep(1000);
32 } catch (InterruptedException e) {
33 e.printStackTrace();
34 }
35 }
36
37 else {
38 //save保存代码
39 //终止当前线程
40 return;
41 }
42 }
43 }
44 }

查看执行结果,5秒后执行结果。

t----->0
t----->1
t----->2
t----->3
t----->4

五、线程调度与优先级

1、分两种:抢占式调度模型与均分式调度模型,java属于前者

2、常用方法:

(1)设置线程的优先级:void setPrority()

(2)获取线程的优先级:int getPrority()

优先级分:1,5,10(最高)

(3)进程让位:static void yield()

(4)合并线程程:t.join() //当前线程阻塞,t线程加入当前线程中

六、线程安全(重点)

参考下一个章节

七、死锁

1、含义:

不出现异常,也不会出现错误,程序僵持,难以调试

2、举例:

 1 package JAVAADVANCE;
2
3 public class TestAdvance37TestThread09 {
4 public static void main(String[] args) {
5 Object o1=new Object();
6 Object o2=new Object();
7 Thread t1=new MyThread1(o1,o2);
8 Thread t2=new MyThread2(o1,o2);
9 t1.start();
10 t2.start();
11 }
12 }
13 class MyThread1 extends Thread{
14 Object o1;
15 Object o2;
16 public MyThread1(Object o1,Object o2){
17 this.o1=o1;
18 this.o2=o2;
19 }
20 public void run(){
21 synchronized (o1){
22 try {
23 Thread.sleep(1000);
24 } catch (InterruptedException e) {
25 e.printStackTrace();
26 }
27 synchronized (o2){}
28 }
29 }
30 }
31 class MyThread2 extends Thread{
32 Object o1;
33 Object o2;
34 public MyThread2(Object o1,Object o2){
35 this.o1=o1;
36 this.o2=o2;
37 }
38 public void run(){
39 synchronized (o2){
40 try {
41 Thread.sleep(1000);
42 } catch (InterruptedException e) {
43 e.printStackTrace();
44 }
45 synchronized (o1){}
46 }
47 }
48 }

程序运行一直不会结束也没有返回

3、解决方案:

程序编写使用时尽量避免synchronized 方法嵌套使用

java进阶(37)--多线程的更多相关文章

  1. Java进阶05 多线程

    链接地址:http://www.cnblogs.com/vamei/archive/2013/04/15/3000898.html 作者:Vamei 出处:http://www.cnblogs.com ...

  2. Java进阶之多线程

    多线程 多线程(multiple thread)是计算机实现多任务并行处理的一种方式. 在单线程情况下,计算机中存在一个控制权,并按照顺序依次执行指令.单线程好像是一个只有一个队长指挥的小队,整个小队 ...

  3. [java进阶]关于多线程的知识点

    线程和进程的区别? 进程: 是程序得一次之星过程,是系统运行程序的基本单位,因此进程是动态的.系统运行一个程序就是从一个进程的创建开始,到进程的结束的过程. 在java中当我们的main函数运行时就是 ...

  4. Java进阶(三)多线程开发关键技术

    原创文章,同步发自作者个人博客,转载请务必以超链接形式在文章开头处注明出处http://www.jasongj.com/java/multi_thread/. sleep和wait到底什么区别 其实这 ...

  5. 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)

    本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...

  6. Java进阶(四十二)Java中多线程使用匿名内部类的方式进行创建3种方式

    Java中多线程使用匿名内部类的方式进行创建3种方式 package cn.edu.ujn.demo; // 匿名内部类的格式: public class ThreadDemo { public st ...

  7. 进阶Java编程(1)多线程编程

    Java多线程编程 1,进程与线程 在Java语言里面最大的特点是支持多线程的开发(也是为数不多支持多线程的编程语言Golang.Clojure方言.Elixir),所以在整个的Java技术学习里面, ...

  8. java进阶视频分享

    更多资源和教程请关注公众号:非科班的科班. 如果觉得我写的还可以请给个赞,谢谢大家,你的鼓励是我创作的动力 课程目录介绍 01.开班仪式02.并发编程专题之多线程基础03.并发编程专题之Java内存模 ...

  9. Java进阶(五)Java I/O模型从BIO到NIO和Reactor模式

    原创文章,同步发自作者个人博客,http://www.jasongj.com/java/nio_reactor/ Java I/O模型 同步 vs. 异步 同步I/O 每个请求必须逐个地被处理,一个请 ...

  10. Java线程间通信方式剖析——Java进阶(四)

    原创文章,同步发自作者个人博客,转载请在文章开头处以超链接注明出处 http://www.jasongj.com/java/thread_communication/ CountDownLatch C ...

随机推荐

  1. C++ Qt开发:Tab与Tree组件实现分页菜单

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍tabWidg ...

  2. 【笔记整理】[案例]使用正则表达式来提取36Kr新闻

    import datetime import json import re import requests class Kr36(object): def __init__(self): self.u ...

  3. 神经网络优化篇:详解其他正则化方法(Other regularization methods)

    其他正则化方法 除了\(L2\)正则化和随机失活(dropout)正则化,还有几种方法可以减少神经网络中的过拟合: 一.数据扩增 假设正在拟合猫咪图片分类器,如果想通过扩增训练数据来解决过拟合,但扩增 ...

  4. Python——Html(HEAD头部)

    HTML中HEAD头部设置(了解) 在HTML中,<head> 元素是文档的头部部分,通常包含了一些关于文档的元信息和链接到外部资源的标签.以下是一些常见的 <head> 元素 ...

  5. 告别复杂排版:Markdown语法指南

    导语:Markdown作为一种轻量级的标记语言,以其简洁.易学的语法和强大的兼容性赢得了广泛的应用.本文将为您详细介绍Markdown的起源.基本语法及其在写作.博客.项目管理等场景的应用,带您领略这 ...

  6. C#汉诺塔递归算法实现

    目录: 一.什么是递归 1.先来看一下一个递归的例子 2.递归的基本原理 二.汉诺塔问题 1.汉诺塔的故事 2.回到编程,汉诺塔问题主要就是解决这个问题: 3.怎么解决汉诺塔问题 要解决汉诺塔问题就要 ...

  7. Golang 命名返回值和普通返回值

    1.概述 在Go语言中,函数可以有命名返回值和普通(匿名)返回值.命名返回值会被视为定义在函数顶部的变量,并且在使用 return 语句返回时,不再必须在其后面指定参数名,也就是支持"裸&q ...

  8. 云图说丨初识数据工坊DWR

    摘要:数据工坊DWR是一款近数据处理服务,通过易用的工作流编排和开放生态的数据处理算子,能够在云上实现图像.视频.文档.图片等数据处理业务. 本文分享自华为云社区<[云图说]第236期 初识数据 ...

  9. 破解数据匮乏现状:纵向联邦学习场景下的逻辑回归(LR)

    摘要:主要介绍了华为云可信智能计算服务(TICS)采用的纵向联邦逻辑回归(LR)方案. 本文分享自华为云社区<纵向联邦学习场景下的逻辑回归(LR)>,作者: 汽水要加冰. 海量训练数据是人 ...

  10. 开心档之MySQL 创建数据表

    MySQL 创建数据表 创建MySQL数据表需要以下信息: 表名 表字段名 定义每个表字段 语法 以下为创建MySQL数据表的SQL通用语法: CREATE TABLE table_name (col ...