java线程(1)-线程初步

1.并行和并发

并行和并发是即相似又有区别:
并行:指两个或者多个事件在同一时刻点发生。
并发:指两个或多个事件在同一时间段内发生
在操作系统中,并发性是指在一段事件内宏观上有多个程序在同时运行,但是单CPU系统中,每一时刻仅能有一道程序执行。故微观上这些程序只能是分时交替执行
单核处理器的计算机肯定是不能并行的处理多个任务的,只能是多个任务在单个CPU上并发运行,同理,线程也是一样的,从宏观角度上理解是并行运行的,但是从微观角度上分析却是串行运行的,即一个线程一个线程的去运行,当系统只有一个CPU时,线程会以某种顺序执行多个线程,我们把这种情况称之为线程调度

2.理解进程和线程

进程和线程:
进程是指一个内存中运行中的应用程序,每一个进程都有自己独立的一块内存空间,一个应用程序可以同启动多个进程。
大多数的时候,操作系统都不需要一个进程方法其他进程的空间,也就是说进程之间的通信是很不方便的。此时我们引入“线程”这门技术,来解决这个问题
线程是指进程中一个执行任务,一个进程可以同时并发运行多个线程,如:多线程下载软件。
多任务系统:该系统可以运行多个进程,一个进程可以执行多个任务,一个进程可以包含多个线程

一个进程至少有一个线程,为了提高效率,可以在一个进程中开启多个执行任务,即多线程

多进程:操作系统中同时运行的多个程序
多线程:在同一个进程中同时运行的多个任务

在操作系统中允许多个任务,每一个任务就是一个进程,每一个进程也可以同时执行多个任务,每一个任务就是线程

进程和线程的区别:
进程:有独立的内存空间,进程中的数据存放空间(堆空间和栈空间)是独立的,至少有一个线程
线程:堆空间是共享的,栈空间是独立的,线程消耗的资源也比进程小,相互之间可以影响的,又称为轻型进程或进程元
因为一个进程中的多个线程是并发的,那么从微观角度来考虑也是有先后顺序的,那么哪一个线程执行完全取决于CPU调度器(JVM来调度),程序员是控制不了的
我们可以把线程并发性看做是多个线程在瞬间抢CPU资源,谁抢到了资源谁就运行,这也就造成了多线程的随机性
java程序的进程里至少包含主线程和垃圾回收线程(后台线程)

线程调度:
计算机通常只有一个CPU时,在任意时刻只能执行一条计算机指令,每一个进程只有获取CPU的使用权才能执行指令。所谓多进程并发性,从宏观上来看,其实就是各个进程轮流获得CPU的使用权,分别执行各自的任务
那么,在可运行池中,会有多个线程处理就绪状态等到CPU,JVM就负责了线程的调度
JVM采用的是抢占式调度,没有采用分时调度,因此可能造成多线程执行结果的随机性。

3.多线程的优势

多线程作为一种多任务,并发的工作方法,当然有其存在的优势:
1.进程之前不能共享内存,而线程之间共享内存(堆内存)则很简单
2.系统创建进程时需要为该进程重新分配系统资源,创建线程则代价小的多,因此实现多任务并发时,多线程效率更高
3.java语言本身内置多线程功能的支持,而不是单纯作为底层系统的调度方式,从而简化了多线程编程

4.创建一个简单的多线程

在java代码中如何去运行一个进程:
方式1:Runtime类的exec方法
方式2:ProcessBuilder的start方法

//在java中如何开启一个进程:运行记事本程序
public class ProcessDemo{public static voild main(String[] args) throws Exception{//方式1:使用Runtime类的exec方法Runtime runtime = Runtime.getRuntime();runtime.exce("notepad");//方式2:使用ProcessBuilder的start方法ProcessBuilder pb = new ProcessBuilder("notepad");pb.start();
}
}

5.使用继承方式和实现方式创建并启动线程

创建和启动线程,传统有两种方法:
方式1:继承Thread类
方式2:实现Runnable接口
线程类:Thread类(java.lang.Thread)和Thread的子类才能称之为线程类(API有详细例子)
方式1:继承Thread类
步骤:
1.定义一个类A继承于java.lang.Thread类
2.在A类中覆盖Thread类中的run方法
3.我们在run方法中编写需要执行的操作->run方法里的线程执行体
4.在main方法(线程)中,创建线程对象,并启动线程

创建线程类: A类 a = new A类();
调用线程对象的start方法,a.start();//启动一个线程

注意:千万不要调用run方法,如果调用run方法,好比是对象调用方法,依然还是只有一个线程,并没有开启新的线程.

方式1:继承Thread类

//计算大于某一规定值的质数的线程可以写成:
//1.定义Thread的集成类
class PrimeThread extends Thread{long mainPrime;public PrimeThread(long mainPrime){this.mainPrime = mainPrime;}public void run(){//TODO}
}//2.调用线程类.创建并启动一个线程
PrimeThread p = new PrimeThread(143);
p.start();//注意是调用start方法

方式2:实现Runnable接口
步骤:
1.定义一个类A继承于java.lang.Thread类
2.在A类中覆盖Thread类中的run方法
3.我们在run方法中编写需要执行的操作->run方法里的线程执行体
4.在main方法(线程)中,创建线程对象,并启动线程

创建线程类: Thread(Runnable target);//分配新的Thread对象
调用线程对象的start方法,a.start();//启动一个线程

//方式2,是声明实现 Runnable 接口的类
class PrimeRun implements Runable{long mainPrime;public PrimeRun(long mainPrime){this.mainPrime = mainPrime;}public void run(){//TODO}
}//创建并启动一个线程:
PrimeRun p = new PrimeRun(143);
Thread t = new Thread(p);
t.start();
//每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。

6.使用匿名内部类来创建线程

只适用于某一个类只适用一次的情况。
匿名内部类其实就是把5中步骤1,2,3放在4中写,例如创建一个Runnable接口的匿名内部类,上面的改成:

new Thread(new Runnable(){public void run(){//TODO}
}).start();

通过继承方式的内部类也是可以这样写的,写的时候就不用声明继承了,直接在{}里面写run()方法就可以了。

new Thread(){public void run(){//TODO}
}.start();

这种方式用的比较少

7.案例

我们写一个案例来具体说明:
需求:有50个苹果,请三个小朋友来吃,A,B,C三个人可以同时吃苹果,用多线程来实现
分析:
可以先定义线程对象,然后启动线程
方法:
可以用我们上面的两种方法来实现
方式1:使用继承Thread方法
但是下面类型创造出来多线程会每个线程都吃50个苹果

/*** 用继承方法来完成吃苹果的多线程需求*/
//创建一个线程类
class Person extends Thread{private int num = 50;//构造器,调用Thread的方法赋值public Person(String name){super(name);}public void run(){for (int i = 0; i < 50; i++) {if (num > 0){System.out.println(super.getName()+"吃了编号为"+ num-- +"的苹果");}}}
}public class AppleExtends {public static void main(String[] args) {//创建桑个线程new Person("小A").start();new Person("小B").start();new Person("小C").start();}
}

方式2:使用实现Runnable方式来实现

class Apple implements Runnable{private int num = 50;public void run(){for (int i = 0; i < 50; i++) {if (num > 0){System.out.println(Thread.currentThread().getName()+"吃了编号为"+ num-- +"的苹果");}}}
}public class appleImplements {public static void main(String[] args) {//创建桑个线程Apple a = new Apple();new Thread(a,"小A").start();new Thread(a,"小B").start();new Thread(a,"小C").start();}
}

两种方式的区别分析:
继承方式:
1.java中类是单继承的,如果继承了Thread了,该类就不能再有其他的直接父类了
2.从操作上分析,继承方式更简单,获取线程名字也简单(操作上,更简单)
3.从多线程共享一个资源上分析,继承方式不能做到共享

实现接口方式:
1.java中类可以多实现接口,此时该类还可以继承其他类,并且还可以实现其他接口(设计上更优雅)
2.从操作上分析,实现方式稍微复杂点,获取线程名字也稍微复杂,得使用Thread.currentThread()来获取当前线程的引用,使用Thread.currentThread().getname()来获取当前线程的名字
3.从多线程共享一个资源分析,实现方式可以做到共享

转载于:https://www.cnblogs.com/cenyu/p/6149838.html

第21章 java线程(1)-线程初步相关推荐

  1. 第五章 如何使用java中的线程打印偶数和奇数

    你有两个线程.您需要使用一个线程打印奇数,使用另一个线程打印偶数.您需要以自然顺序打印最多 MAX. 例如: 如果 MAX 为 10,则需要打印: 1 2 3 4 5 6 7 8 9 10 所以 1 ...

  2. 第二十三章 Java线程与操作系统关系

    Java线程与操作系统关系 Java线程的实现方式 线程的实现 内核线程实现 用户线程实现 用户线程加轻量级进程混合实现 Java线程的实现 Java线程调度 线程状态转换 线程安全 线程安全分类 线 ...

  3. 对Java多线程编程的初步了解,实现多线程的三种方式以及多线程并发安全的线程同步机制

    什么叫进程?什么叫线程? 进程相当于一个应用程序,线程就是进程中的一个应用场景或者说是一个执行单元,一个进程可以启动多个线程,每个线程执行不同的任务,一个线程不能单独存在,他必须是进程的一部分,当进程 ...

  4. java 手编线程池_死磕 java线程系列之自己动手写一个线程池

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. (手机横屏看源码更方便) 问题 (1)自己动手写一个线程池需要考虑哪些因素? (2)自己动手写 ...

  5. java 线程 操作系统线程_线程基础:线程(1)——操作系统和线程原理

    1.概述 我在写"系统间通信技术专栏"的时候,收到很多读者的反馈.其中有一部分读者希望我抽空写一写自己关于对Java线程的使用经验和总结.巧的是,这个月我所在的技术团队也有很多同事 ...

  6. java 添加一个线程、创建响应的用户界面 。 演示示例代码

    javajava 添加一个线程.创建响应的用户界面 . 演示示例代码 来自thinking in java 4 21章  部分的代码  夹21.2.11 thinking in java 4免费下载: ...

  7. 《JAVA编程思想》学习笔记:第21章(并发)

    目录 Java编程思想(一)第1~4章:概述 Java编程思想(二)第5章:初始化和清理 Java编程思想(三)第6章:访问权限 Java编程思想(四)第7章:复用类 Java编程思想(五)第8章:多 ...

  8. 并发编程基础篇——第二章(如何创建线程)

    上节讲了基础概念,本章正式进入线程专题,对基础薄弱的同学可以好好看本章!! 1.Thread匿名子类 我们可以通过下面的代码来直接创建一个线程. // 构造方法的参数是给线程指定名字,推荐 Threa ...

  9. Java并发编程——线程池的使用

    在前面的文章中,我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统 ...

最新文章

  1. NR 5G RLC无线链路控制
  2. StringFarmat控制字符串居中显示
  3. for循环执行 mybatis_Mybatis中使用循环遍历
  4. while用法_when 和 while 的用法区别
  5. redmine一键安装
  6. c语言调用自己编译的头文件,写自己的头文件 ——C语言的多文件编译
  7. 如果财富都在部分人手里会怎样?
  8. 【LoadRunner技术讲座8】LoadRunner函数中的几个陷阱
  9. java+jdk+1.6.0+45+64_jdk1.6.0_45.tar.gz
  10. 在try中写了return,后面又写了finally,是先执行return还是先执行fianlly
  11. APP社交类源代码分享直接上车
  12. 【时间序列分析】14.平稳序列的参数估计与白噪声检验
  13. 怎么做好客户关系管理培训PPT课件?
  14. 微信小程序如何测试?
  15. 什么技术都只懂一点的蹩脚程序员
  16. 代数表达式c语言表达式,[单选] 设floata=2,b=4,c=3;,以下C语言表达式与代数式(a+b)+c计算结果不一致的是()...
  17. 浏览器屏蔽百度推广广告
  18. uniapp返回上一页并刷新数据
  19. 【CTFhub】web-信息泄露-备份文件下载-网站源码_WriteUp
  20. GTD和掌握Omni系列效率工具

热门文章

  1. cmake构建NNIE工程
  2. [置顶]常用存储过程集锦
  3. linux下NFS、FTP使用讲解
  4. 使用Gitosis搭建Git服务器
  5. 第15条:使可变性最小化
  6. 0145129实验报告(五)
  7. 【iOS开发-60】案例学习:多组数据的tableView设置、添加右側组索引、多层数据模型设置以及valueForKeyPath...
  8. 关于12306的一点思考
  9. Svchost进程应用技巧
  10. C++中怎么调用C函数