【多线程】Java线程模型
来源:互联网 发布:java基础入门课后答案 编辑:程序博客网 时间:2024/05/16 00:26
1. 相关概念:
- 程序:安装在磁盘上的一段指令的集合,是静态的。
- 进程:是运行中的程序,是动态的。每个进程有独立的资源空间。
- 线程:又称轻量级进程,是程序执行流的最小单元,是程序中单一的顺序控制流程。线程是进程中的一个实体,是被系统独立调度和分派的基本单位。
- 多线程:在单个程序中,可以同时运行多个不同的线程执行不同的任务
线程才是真正干活的,进程无非是分配了资源的空间,一个进程中有多个线程,线程共享了进程的资源空间。所以当一个程序开始运行,至少已经开启了一个进程。
2. 线程模型:
2.1.通过继承Thread类创建线程
- 普通Java类如果继承了Thread类就成了一个线程类,并可以通过该类的start方法启动线程,执行线程代码。
- Thread类的子类可以直接实例化,但是在子类中必须覆盖run方法才能真正运行线程代码
class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } //在子类中重写了thread类的run方法 public void run() { // compute primes larger than minPrime . . . } }
//实例化线程类的子类PrimeThread p = new PrimeThread(143); p.start();
2.2 通过实现Runnable接口创建线程
实现Runnable接口的类必须借助Thread类才能创建线程。通过Runnable接口创建线程分为两步;
- 创建实现Runnable接口的类的实例;
- 创建一个Thread类对象,将第一步实例化得到的Runnable对象作为参数传入Thread类的构造方法;
- 通过Thread类的start方法启动线程
//创建实现Runnable接口的类的实例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); //将实例化得到的Runnable对象作为参数传入Thread类的构造方法; new Thread(p).start();
API:
http://tool.oschina.net/apidocs/apidoc?api=jdk-zh
3. Thread类常用方法:
static Thread currenThread():返回对当前正在执行的线程对象的引用。
long getId():返回该线程的标识符。
String getName():返回该线程的名称。
int getPriority(): 返回线程的优先级。
Thread.State getState():返回该线程的状态。
void interrupt():中断线程。
boolean isAlive():测试线程是否处于活动状态。
void join():等待该线程终止
static void sleep(long millis):线程休眠
void start():使该线程开始执行;Java 虚拟机调用该线程的 run 方法。
4. Code Demo:
4.1 继承Thread类创建多个线程
public class ThreadDemo { public static void main(String[] args) { //产生一个线程类对象 HelloThread h1=new HelloThread(); //自定义线程名称setName h1.setName("线程1"); //调用线程类实例的start方法,启动线程,就会调用线程实例的run方法执行 h1.start(); //一个线程类可以创建多个线程实例 //Thread(String name)方法在实例化线程的同时指定了线程名称 HelloThread h2=new HelloThread("线程2"); h2.start(); }}class HelloThread extends Thread{ //线程初始化 public HelloThread() { } //带参数的线程初始化 public HelloThread(String name) { super(name); } //重写父类的run方法 @Override public void run() { for(int i=0;i<5;i++){ //获取线程的名称getName System.out.println(this.getName()+"--"+i); } }}
4.2 实现Runnable接口创建多个线程
public class HelloRunnableDemo { public static void main(String[] args) { HelloRunnable hr=new HelloRunnable(); Thread t1=new Thread(hr,"线程A"); t1.start(); Thread t2=new Thread(hr,"线程B"); t2.start(); }}class HelloRunnable implements Runnable{ @Override public void run() { for(int i=0;i<5;i++){ //获取线程的名称getName System.out.println(Thread.currentThread().getName()+i); } }}
一般情况下,使用第二种方法,即实现Runnable接口来创建线程,主要是因为:
- 避免单继承的局限,一个类可以实现多个接口,但只能继承一个类
- 适合资源的共享
我们用一个多线程买票的例子说明二者的区别:
用继承Thread的方法创建两个线程对象,s1和s2,各自不能共享数据,实际上是每个线程都有5张票。类似于“计划经济”,每个线程有固定的指标,彼此互不影响。
public class SharedDataThreadDemo { public static void main(String[] args) { TicketThread s1=new TicketThread("窗口1:"); s1.start(); TicketThread s2=new TicketThread("窗口2:"); s2.start(); }}class TicketThread extends Thread{ private int tickets=5; public TicketThread(String name){ super(name); } @Override public void run() { while(true){ System.out.println(this.getName()+(tickets--)); if(tickets<1){ break; } } }}
通过实现Runnable接口,只产生了一个对象,但是可以创建任意多个线程,这些线程都是共享对象的属性的。
也就是说所有窗口提供的票数是固定的,不管从哪里买,票数都会发生变化
public class SharedDataThreadDemo { public static void main(String[] args) {/* TicketRunnable runnable=new TicketRunnable(); Thread t1=new Thread(runnable,"窗口1"); t1.start(); Thread t2=new Thread(runnable,"窗口2"); t2.start(); }}class TicketRunnable implements Runnable{ private int tickets=5; @Override public void run() { while(true){ System.out.println(Thread.currentThread().getName()+":"+(tickets--)); if(tickets<1){ break; } } }}
- 【多线程】Java线程模型
- java多线程-线程内存模型
- soa---java 多线程-线程内存模型
- Java多线程 -- 线程的栈模型
- 多线程:线程模型-小结
- Java的多线程编程模型2--怎样才线程安全
- Java的多线程编程模型2--怎样才线程安全
- Java多线程编程总结笔记——三线程栈模型与线程的变量
- java多线程学习2-线程栈模型与线程的变量
- Java多线程-(2)线程栈模型与线程的变量
- Java多线程(三):线程栈模型与线程的变量
- java多线程详解一线程的内存模型和线程特性
- java多线程内存模型
- Java多线程内存模型
- Java多线程模型
- Java多线程死锁模型
- java 多线程内存模型
- Java多线程内存模型
- 动态指定报表行对齐方式
- [Google Guava] 1.2-前置条件
- PostgreSQL 断开所有连接用户、删除数据库、修改表名称
- 欢迎使用CSDN-markdown编辑器
- 在RedHat 6.4安装Redis集群
- 【多线程】Java线程模型
- 1066. Root of AVL Tree (25)
- [Google Guava] 1.3-常见Object方法
- 第15周OJ实践11 包含B的字符串
- 开发一个app需要考虑的问题
- web开发
- Xamarin.iOS-UITableView详细使用说明【控件篇】
- 解决微信浏览器video全屏的问题
- java学习历程(2):web项目入手(MVC)