JavaSE入门学习50:多线程编程(一)
一进程和线程
(1)进程和线程的基本概念
进程:程序(任务)的执行过程;持有资源(共享内存,共享文件)和线程。
线程:是一个程序内部的顺序控制流。
我们生活中的进程例子很多,一个进程就相当于一个你在电脑上启动的程序。比如我们打开最常用的聊天工具
QQ,也可以打开Java的开发工具Eclipse等等。这些都算Window操作系统上的一个进程。
对于Window操作系统上一个线程,还是拿QQ进程和Eclipse进程来举例,QQ进程中的文字聊天和收发文件就是
其中的两个线程;Eclipse进程中的源代码文件编辑、源代码编译和语法校验就是其中的三个线程。
通过上面的知识可以得出:
1)一个进程可以有多个线程;
2)线程是系统中最小的执行单元;
3)同一进程中有多个线程;
4)线程共享进程的资源。
(2)线程和进程的区别
每个进程都有独立的代码和数据空间(进行上下文),进程间的切换会有较大的开销。多进程指的是在操作系统中
同时运行多个任务(程序)。
线程可以看成轻量级的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线
程切换的开销小。多线程指的是在同一程序中有多个顺序流相同时执行。
(3)线程交互
线程间的通信包括互斥和同步。
互斥:通常表现在多个线程竞争同一资源,比如这里只有一只笔,同时有几个人要进行签到,但资源(笔)唯一,
线程(人)之间就存在竞争关系,并且同一时间只有一个线程(人)能够持有这个资(笔)。
同步:同步就是协同步调,按预定的先后次序进行运行,如进程、线程同步,可理解为进程或线程A和B一块配
合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作。
二Java多线程
Java多线程是通过java.lang.Thread类来实现的。VM启动时会有一个由主方法(public static void main(){})所定义
的线程。可以通过创建Thread类的实例来创建新的线程。每个线程都是通过某个特定Thread类的对象所对应的方法
run()来完成其操作的,方法run()称为线程体。通过调用Thread类的start()方法来启动一个线程。
(1)Thread类
API中定义的Thread类:
线程是程序中的执行线程。Java虚拟机允许应用程序并发地运行多个执行线程。 每个线程都有一个优先级,高优
先级线程的执行优先于低优先级线程。每个线程都可以或不可以标记为一个守护程序。当某个线程中运行的代码创建
一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,
新线程才是守护程序。
当Java虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main()方法。Java虚拟机会继续
执行线程,直到下列任一情况出现时为止:
1)调用了Runtime类的exit()方法,并且安全管理器允许退出操作发生。
2)非守护线程的所有线程都已停止运行,无论是通过从对run()方法的调用中返回,还是通过抛出一个传播到run()
方法之外的异常。
创建新执行线程有两种方法。一种方法是将类声明为Thread类的子类。该子类应重写Thread类的run()方法。接
下来可以分配并启动该子类的实例。例如,计算大于某一规定值的质数的线程可以写成:
- class PrimeThread extends Thread {
- long minPrime;
- PrimeThread(long minPrime) {
- this.minPrime = minPrime;
- }
- public void run() {
- //compute primes larger than minPrime
- . . .
- }
- }
然后,下列代码会创建并启动一个线程:
- PrimeThread p = new PrimeThread(143);
- p.start();
创建线程的另一种方法是声明实Runnable接口的类。该类然后实现run()方法。然后可以分配该类的实例,在创
建Thread类时作为一个参数来传递并启动。采用这种风格的同一个例子如下所示:
- class PrimeRun implements Runnable {
- long minPrime;
- PrimeRun(long minPrime) {
- this.minPrime = minPrime;
- }
- public void run() {
- // compute primes larger than minPrime
- . . .
- }
- }
然后,下列代码会创建并启动一个线程:
- PrimeRun p = new PrimeRun(143);
- new Thread(p).start();
每个线程都有一个标识名,多个线程可以同名。如果线程创建时没有指定标识名,就会为其生成一个新名称。
Thread类中定义关于线程优先级的字段:
Thread类中定义的构造方法:
Thread类中定义的方法:
(2)Runnable接口
API中描述的Runnable接口:
Runnable接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为run()的无参数方法。
设计Runnable接口的目的是为希望在活动时执行代码的对象提供一个公共协议。例如,Thread类实现了Runnable接
口。激活的意思是说某个线程已启动并且尚未停止。
此外,Runnable接口为非Thread子类的类提供了一种激活方式。通过实例化某个 Thread类实例并将自身作为运
行目标,就可以运行实现Runnable接口的类而无需创建Thread类的子类。大多数情况下,如果只想重写run()方法,
而不重写其他Thread类方法,那么应使用Runnable接口。这很重要,因为除非程序员打算修改或增强类的基本行
为,否则不应为该类创建子类。
Runnable接口中只定义了一个方法:
(3)线程的创建与启动
Java中可以有两种方式创建新的线程。
第一种:定义线程类实现Runnable接口
Thread myThread=new Thread(target) //target为Runnable接口类型。
Runnable接口中只有一个方法:
public void run();//定义线程运行体。
使用Runnable接口可以为多个线程提供共享的数据。
在实现Runnable接口的类的run()方法中可以使用Thread的静态方法:
public static Thread correntThread() 获取当前线程的引用
第二种:定义线程类继承Thread类
定义一个Thread类的子类并重写其run()方法如:
class MyThread extends Thread{
public void run(){...}
}
然后生成该类的对象:
MyThread myThread = new Mythread(...)
实例:
TestThread1.java源代码:
方法调用的顺序执行,也就是先执行Runnable1线程,再执行主线程。
- public class TestThread1 {
- public static void main(String args[]) {
- <span style="color:#ff6600;">Runner1 r = new Runner1();
- r.run();</span>
- for(int i=0; i<10; i++) {
- System.out.println("主线程:------" + i);
- }
- }
- }
- class Runner1 implements Runnable {
- public void run() {
- for(int i=0; i<10; i++) {
- System.out.println("Runner1线程:" + i);
- }
- }
- }
运行结果:
线程启动后的交替执行,其中最重要的是Thread类的start()方法,即Runnable1线程和主线程交替执行。
- public class TestThread1 {
- public static void main(String args[]) {
- <span style="color:#ff6600;">Runner1 r = new Runner1();
- Thread t = new Thread(r);
- t.start();</span>
- for(int i=0; i<10; i++) {
- System.out.println("主线程:------" + i);
- }
- }
- }
- class Runner1 implements Runnable {
- public void run() {
- for(int i=0; i<10; i++) {
- System.out.println("Runner1线程:" + i);
- }
- }
- }
运行结果:
使用继承Thread类的修改后的代码:
- public class TestThread1 {
- public static void main(String args[]) {
- <span style="color:#ff6600;">Runner1 r = new Runner1();
- r.start();</span>
- for(int i=0; i<10; i++) {
- System.out.println("主线程:------" + i);
- }
- }
- }
- <span style="color:#ff6600;">class Runner1 extends Thread</span> {
- public void run() {
- for(int i=0; i<10; i++) {
- System.out.println("Runner1线程:" + i);
- }
- }
- }
运行结果:
推荐使用实现Runnable接口的线程类来进行多线程的创建与启动,比较灵活。
关于两种方法创建线程的不同
第一:创建线程只有继承Thread类和实现Runnable接口两种方式(Thread也是实现了Runnable接口);
第二:若以继承Thread类方式创建线程则这个类的实例就可以重写Thread类的几十个方法,注意是好几十个方
法;
第三:若以实现Runnable接口的方式创建线程则仅仅只有一个run()方法可供重写(注意是只有一个);
实现Runnable接口创建的线程最终还是要通过将自身实例作为参数传递给Thread类然后执行,当你要为一个没
有继承Thread类的类创建线程,而且只想让这个类的实例调用run()方法执行任务,这时候Runnable接口就相当于为
你的目标类提供了一个激活方式,设计该接口的目的是为了那些希望在激活时执行代码的对象提供一个公共协议,激
活的意思是说某个线程已启动并且尚未停止。
这两种创建线程的方法本身没有什么不同,一个是实现Runnable接口,一个是继承Thread类。而使用实现
Runnable接口这种方法:1.可以避免Java的单继承的特性带来的局限性;2.适合多个相同程序的代码去处理同一个资
源的情况,把线程同程序的代码及数据有效分离,较好地体现了面向对象的设计思想。开发中大多情况下都使用实现
Runnable接口这种方法创建线程。
from: http://blog.csdn.net/erlian1992/article/details/51706914
JavaSE入门学习50:多线程编程(一)相关推荐
- python学习笔记——多线程编程
python学习笔记--多线程编程 基础不必多讲,还是直接进入python. Python代码代码的执行由python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主循环中,同时 ...
- JavaSE入门学习51:多线程编程(二)
二Java多线程 (4)线程的状态 线程状态转换示意图: 线程控制的基本方法: 1)sleep()方法 可以调用Thread的静态方法: public static void sleep(long m ...
- JavaSE入门学习47:Socket网络通信编程(一)
今天既然我们学习Java的Socket网络通信编程,那么在我们的现实生活中那些是Socket编程的应用呢?可以想象 我们最常用的聊天工具软件QQ就是,当然MSN也是啦. 一网络基础知识 两台计算机通过 ...
- JavaSE入门学习1:计算机基础知识
一计算机概述 计算机(Computer)全称:电子计算机,俗称电脑.是一种能够按照程序运行,自动.高速处理海量数据的现代化 智能电子设备.由硬件和软件所组成,没有安装任何软件的计算机称为裸机.常见的形 ...
- 3.1_15 JavaSE入门 P14 【多线程】同步、匿名内部类、死锁、生命周期
相关链接 Excel目录 目录 P14 [进阶]多线程.同步.匿名内部类.死锁.生命周期 1 概述 1.1 并行&并发 1.2 主方法是多线程的吗? 2 多线程实现 2.1 方式一:继承Thr ...
- JavaSE入门学习38:Java集合框架之迭代器
一Iterator接口 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层 结构.迭代器通常被称为"轻量级"对象,因为创建它的代价小 ...
- APUE学习之多线程编程(二):线程同步
为了保证临界资源的安全性和可靠性,线程不得不使用锁,同一时间只允许一个或几个线程访问变量.常用的锁有互斥量,读写锁,条件变量 一.互斥量 互斥量是用pthread_mutex_t数据类型表示的,在使用 ...
- JavaSE入门学习34:Java集合框架之Collection接口、子接口及其实现类
一Collection接口 Collection接口定义了存取一组对象的方法,其子接口Set.List和Queen分别定义了存储方式. 使用Collection接口需要注意: 1Collection接 ...
- Arduino 开发入门 学习笔记 Arduino编程基础
11月2日至5日 事务缠身 11月6日 继续坚持 Arduino语言 其实是基于C/C++的嵌入式设备开发框架,核心库文件提供的API使传统开发方式中各个寄存器的意义以及寄存器配置过程变得透明. 增强 ...
最新文章
- 你管这破玩意叫 CPU ?
- Linux无线网卡的工作模式
- 定时任务之crond服务
- ffmpeg-filter 入门
- WAS6.1在JDK1.5环境下JSP无法编译问题
- 顺丰同城宣布苏炳添出任首位品牌代言人
- Sharding-Sphere,Sharding-JDBC_分库分表介绍_Sharding-Sphere,Sharding-JDBC分布式_分库分表工作笔记002
- 换了路由器电脑都连不上网了_换了新路由器电脑连不上网
- 知识管理系统Data Solution研发日记之七 源代码与解决方案
- numeric比较大小 数据库_SQL中NUMERIC和DECIMAL的区别
- win7+ubuntu16.04以及win10+ubuntu18.04双系统安装
- 原型模型| 软件工程
- 关于电子邮件客户端设计中QQ邮箱授权码问题。(运行提示535错误,说授权码error。)
- CCF认证练习题-西西艾弗岛的购物中心
- vue 移动端头像裁剪_vue头像上传裁剪组件_一个漂亮的Vue组件,用于图像裁剪和上传...
- 一分钟教你如何使用edge浏览器玩4399小游戏
- Cam350导入Allegro的*.rou文件
- 网易MySQL数据库工程师微专业学习笔记(十四)
- 如何快速选对创意 —— 阿里妈妈广告创意优选
- 黎曼猜想证明现场:3分钟核心讲解、提问陷沉默,同行不予置评 | 全程视频+PPT...