线程与进程的关系

进程 --运行中的程序。进程有如下特征:
1).独立性。拥有自己的资源,拥有自己独立的内存区。
通常来说,一个进程的内存空间,是不允许其他进程访问的。
但像Windows,如A进程可以通过某种方式修改其他进程的内存值。
2).动态性。程序是静止的,运行起来才叫进程。
3).并发性。一个操作系统可以同时“并发(concurrent)”运行多个进程。
线程 --进程中的“并发(concurrent)”执行流,轻量级进程。

线程与进程的典型区别:Process(进程)是有独立内存的,因此创建Process的成本比创建线程的成本高。

什么是“并发”?什么是“并行”?
1)并发:即使只有一个CPU,多个进程、或多个线程在CPU上【快速轮换】的执行。在同一个时刻,只有与CPU个数相同的进程真正在执行,其他进程都处于等待状态。--对用户来说,[感觉]是多个进程在同时执行。

2)并行(Parallel):必须有一个以上的cpu,在同一时刻,至少有与CPU个数相同的进程[真正]在执行。

多线程的好处
1)功能上类似多进程;
2)创建成本低,效率高;
3)所有线程共享进程的内存,因此线程之间的通信非常方便。

Java创建多线程的方法(3种):(注意 Java默认有个main方法主线程的执行体)

启动线程:调用Thread对象的start()方法,千万不要调用run()方法。就是普通方法的调用,就不会启动多线程了。
a)继承Thread,重写一个run()方法,---这个run方法就是线程执行体(就是该线程将要做的事情)。
举列说明1:

public class Test extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {// Thread.currentThread()用于获取当前正在运行的线程System.out.println(Thread.currentThread().getName() + ",i=" + i);}}public static void main(String[] args) {new Test().start();// 创建匿名实例并启动线程}
}

b)实现Runnable接口,重写run方法。--推荐
举例说明2:

public class Test implements Runnable {@Overridepublic void run() {for (int i = 0; i < 100; i++) {// Thread.currentThread()用于获取当前正在运行的线程System.out.println(Thread.currentThread().getName() + ",i=" + i);}}public static void main(String[] args) {new Thread(new Test()).start();// 这里把Runnable对象包装成Thread对象。}
}

c)实现Callable(就是Runnable增强版),重写call方法(有返回值,可以声明抛出异常)。
举例说明3:

public class Test implements Callable<Integer> {@Overridepublic Integer call() throws Exception {for (int i = 0; i < 100; i++) {// Thread.currentThread()用于获取当前正在运行的线程System.out.println(Thread.currentThread().getName() + ",i=" + i);}return 100;}public static void main(String[] args) {// 将Callable包装成FutureTask,再包装成Thread,最后启动线程new Thread(new FutureTask<Integer>(new Test())).start();;}
}

创建线程方式的对比,创建线程的方式可分为2类:
1。继承Thread类;2。实现Runnable或Callable接口。

总的来说,实现接口的方式更好,原因如下:
1.实现接口之后,依然可以继承其他类;但如果继承了Thread类,就无法继承其他类了。
2.实现接口时,可以让多个线程共享同一个Runnable对象。可以更好的实现代码与数据的分离,形成更清晰的逻辑。

线程的状态(当调用start()方法之后,只是启动了线程,线程并不会立即执行):
新建:刚刚创建出来的Thread对象。
就绪:调用start()之后,处于就绪状态。
从就绪到运行:是不可控的,靠线程调度器来分配。
从就绪到运行:靠线程调度器来分配(yield()方法可以主动的让出cpu,进入就绪状态)。
阻塞:调用sleep()、IO阻塞、等待同步锁、等待通知等将进入阻塞Blocked状态;sleep()时间到、IO阻塞解除、获取同步锁、收到通知后等将进入就绪状态。
正常死亡:线程执行体执行完成;遇到了未捕获的异常。

控制线程的方法:

Join线程:启动一条线程,多条线程并发执行,被joined线程必须先执行完成。
举例说明:

class JoinThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {// Thread.currentThread()用于获取当前正在运行的线程System.out.println(Thread.currentThread().getName() + ",i=" + i);}}
}public class Test {public static void main(String[] args) throws InterruptedException {JoinThread jt1 = new JoinThread();JoinThread jt2 = new JoinThread();for (int i = 0; i < 100; i++) {System.out.println("主线程正在执行:i=" + i);if (i == 20) {// 主线程执行到此处时,必须等到jt1、jt2执行完后,主线程才能继续向下执行。jt1.start();// 將jt1这条进程join进来, 等待jt1线程终止。jt1.join();jt2.start();jt2.join();}}}
}

后台线程(Daemon Thread):又称守护线程、精灵线程。如果所有的前台线程结束,它会自动死亡。JVM的垃圾回收器就是一个典型的后台进程。调用Thread对象的setDaemon(true)方法可将指定线程设置为后台线程。

线程暂停:Thread.sleep(100):让线程暂停100ms,并且进入阻塞状态。--推荐(更稳定)
线程让步:Thread.yield():让线程让出cpu,并进入就绪状态。

改变线程的优先级:优先级越高,线程会获得更多的执行机会。
举例说明:(优先级高的先执行)

class PriorityThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 100; i++) {// Thread.currentThread()用于获取当前正在运行的线程System.out.println(Thread.currentThread().getName() + ",i=" + i);}}
}public class Test {public static void main(String[] args) throws InterruptedException {PriorityThread jt1 = new PriorityThread();jt1.setPriority(Thread.MIN_PRIORITY);PriorityThread jt2 = new PriorityThread();jt2.setPriority(Thread.MAX_PRIORITY);jt1.start();jt2.start();System.out.println("~~~~~~主线程结束~~~~~");}
}

Java学习系列(十四)Java面向对象之细谈线程、线程通信(上)相关推荐

  1. Java学习系列(十八)Java面向对象之基于UDP协议的网络通信

    UDP协议:无需建立虚拟链路,协议是不可靠的. A节点以DatagramSocket发送数据包,数据报携带数据,数据报上还有目的目地地址,大部分情况下,数据报可以抵达:但有些情况下,数据报可能会丢失 ...

  2. Java学习系列(十六)Java面向对象之基于TCP协议的网络通信

    TCP/IP的网络分层模型:应用层(HTTP/FTP/SMTP/POPS...),传输层(TCP协议),网络层(IP协议,负责为网络上节点分配唯一标识),物理层+数据链路层). IP地址用于标识网络中 ...

  3. Java学习系列(十九)Java面向对象之数据库编程

    JDBC(Java Data Base Connectivity:java数据库连接):它定义了一组标准的操作数据库的接口,既然是接口,那它就是一种规范,是Java操作数据库的技术规范. Java数据 ...

  4. Java学习系列(十二)Java面向对象之序列化机制及版本

    序列化:内存中的Java对象<-->二进制流 目的:a)有时候需要把对象存储到外部存储器中持久化保存,b)还有时候,需要把对象通过网络传输. 可序列化的对象,Java要求可序列化的类实现下 ...

  5. Java学习系列(十五)Java面向对象之细谈线程、线程通信(下)

    竞争资源(共享资源):如果有多条线程需要并发访问.并修改某个对象,该对象就是"竞争资源".为了避免多个线程"自由竞争"修改共享资源所导致的不安全问题. 线程同步 ...

  6. Java学习系列(十)Java面向对象之I/O流(上)

    IO流 我们知道应用程序运行时数据是保存在内存中的,但由于内存中的数据不可持久保存(如断电或程序退出时数据会丢失),因此需要一种手段将数据写入硬盘或读入内存.面向IO流编程就是一种很好的选择.IO:I ...

  7. JAVA学习第十四课(接口:implements及其基本应用)

    接口: 我们知道抽象类中可以定义抽象方法,也可以定义非抽象方法,当一个抽象类中的方法都是抽象方法的时候,我们就可以定义另一种表现方式:接口(interface),所以接口是一种特殊的抽象类 接口的出现 ...

  8. Java学习第二十四天

    目录 一.冒泡排序 第一步:思路 第二步:代码实现 二.查找 用到的知识 二维数组 通俗理解: 代码: 总结: 二维数组使用方式 使用方式1:动态初始化 二维数组在内存中的存在形式(重要!) 使用方式 ...

  9. Java 基础系列(十六) --- Java中模板引擎的使用

    模板引擎 1 关于动态页面的渲染 2 非模板引擎的弊端 3 模板引擎 3.1 什么是模板引擎? 3.2 Thymeleaf 语法 3.3 模板引擎的使用 4 总结 1 关于动态页面的渲染   渲染就是 ...

最新文章

  1. XML文档类型定义DTD
  2. html请求接口_前端工程师吐后端工程师(第八讲)——接口的开发
  3. ubuntu 重装 nvidia_nvidia-smi指令报错:Failed to initialize NVML: Driver解决
  4. no module named social_django
  5. 微软.NET Framework 4.5.2 RTM正式版
  6. jquery.formValidator表单验证语法
  7. es6 作为属性名的 Symbol
  8. html5tab页高德地图,高德地图系列web篇——目的地公交导航
  9. python写一个类600行代码_带你领略算法的魅力,一个600行代码的分词功能实现(一)...
  10. 传感器市场需求大幅提升 中企能否满足?
  11. 第二次扩大会议(3.19)
  12. python的装饰器、迭代器、yield_python的装饰器,迭代器,生成器(yield)
  13. HP ProLiant DL380 G6内存错误导致WHEA-Logger 47报警的解决
  14. 计算机网络原理第五版课后--习题答案
  15. 基础物理-物质的组成
  16. python打开其他应用程序错误_Python应用程序错误(Udacity)
  17. JSTL 标签大全详解
  18. 亮剑精神--亮码精神
  19. 如何在家自学编程成为一名程序员?
  20. 运行Django项目报错解决,OSError: [WinError 123] 文件名、目录名或卷标语法不正确。

热门文章

  1. 《Python编程实战:运用设计模式、并发和程序库创建高质量程序》—— 导读
  2. 【Unity】第5章 3D坐标系和天空盒
  3. 安装CleanMyMac 3提示软件已损坏
  4. mongodb日志切割
  5. lamp源码安装之二进制MySQL5.6.25安装
  6. 综述:全国软考首遭试卷丢失 20万考生措手不及
  7. 全球最大电子展2018再度起航,镁客网在香港带你深度探讨人工智能
  8. SPI子系统分析之二:数据结构【转】
  9. 向高端应用进军 杰和推高计算四路服务器
  10. Top 5 Agile Project Management Books