您的位置:首页 > 职场人生

黑马程序员——多线程(一)

2015-05-28 22:16 274 查看
------- <a href="http://www.itheima.com"
target="blank">android培训</a>、<a href="http://www.itheima.com"
target="blank">java培训</a>、期待与您交流! ----------

-多线程的概述

1、进程的概念:一个正在执行中的程序; 每一个进程执行都有一个执行顺序。该顺序是一个执行路径,或者叫一个控制单元。

2、线程的概念:进程中的一个独立的控制单元,控制着进程的执行。(一个进程中至少有一个线程)

3、多线程存在的意义

4、多线程的创建方式

5、多线程的特征。

6、Java VM 启动的时候会有一个进程java.exe

该进程中至少一个线程辅助java程序的执行,而且这个线程运行的代码存在于main方法中

该线程称之为主线程。

-多线程的创建方式一

1、定义类继承Thread

2、复写Thread类中的run方法 (作用:将自定义代码存储在run方法中,让线程运行)

3、创建继承了Thread类的对象,调用线程的start方法(作用:就是启动线程,调用run方法)

package day11_Thread;

/**
* 学习多线程(1、进程   2、线程   3、多线程存在的意义   4、多线程的创建方式   5、多线程的特征)
* 进程:是一个正在执行的程序。
* 		每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
* 线程:就是进程中一个独立的控制单元,它控制着进程的执行。
* (一个进程中至少有一个线程)
*
* Java VM 启动的时候会有一个进程java.exe
* 		该进程中至少一个线程辅助java程序的执行,而且这个线程运行的代码存在于main方法中
* 		该线程称之为主线程。
*
* 扩展:其实进一步可以说jvm 启动不止一个线程,还有辅助垃圾回收机制的线程。
*
*
* 一:如何在自定义的代码中,自定义一个线程呢?
* 		通过对查找api文档,ajva已经提供了对线程这类事物的描述,就是Thread类。
*
* 创建线程的第一种方式:继承Thread类。
* 步骤:1、定义类继承Thread
* 		2、复写Thread类中的run方法 (作用:将自定义代码存储在run方法中,让线程运行)
* 		3、创建继承了Thread类的对象,调用线程的start方法(作用:就是启动线程,调用run方法)
*
* 发现运行结果每一次都不同,这是因为多个线程都获取到了cpu执行权,cpu执行到谁,
* 		谁就运行——这就是多线程的一个特征:随机性
*
* @author Administrator
*
*/

class ThreadDemo extends Thread {
public void run() {
for(int i=0;i<1000;i++){
System.out.println("Thread run..."+i);
}
}
}
public class Day11_01_ThreadDemo {

public static void main(String[] args) {
//for(int i=0;i<100;i++)
//	System.out.println("hello world ! "+i);

ThreadDemo t = new ThreadDemo();//创建一个线程
t.start();//开启程序并执行该线程的run方法
//t.run();//仅仅是对象方法的调用,线程虽然创建了,但并没有执行(面试考点)

for(int i=0;i<1000;i++){
System.out.println("mainThread run......"+i);
}
}

}


-获取线程对象及其名称

每个线程都有自己默认的编号名称:Thread-编号,该编号从0开始。

static Thread currentThread():获取当前线程对象

getName():获取线程的名称

设置线程名称:通过setName()方法或者构造函数

-多线程练习1:创建两个线程,与主线程main交替执行

package day11_Thread;

/**
* 多线程练习1:创建两个线程,与主线程main交替执行
* @author Administrator
*/

class ThreadPractice1 extends Thread {

//private String name;
public ThreadPractice1(String name) {
//this.name = name;
super(name);
}

public void run() {
for(int i=0;i<100;i++){
//System.out.println(name+" Thread run..."+i);
//System.out.println(this.getName()+" Thread run..."+i);
System.out.println((Thread.currentThread()==this)+"...."+this.getName()+" Thread run..."+i);
}
}
}

public class Day11_04_ThreadPractice1 {

public static void main(String[] args) {

ThreadPractice1 t1 = new ThreadPractice1("firstName");
ThreadPractice1 t2 = new ThreadPractice1("secondName");
t1.start();
t2.start();

for(int i=0;i<100;i++){
System.out.println("mainThread run..."+i);
}
}

}


-线程的状态

创建——start()——>运行——sleep(time)——>冻结

冻结——notify()/notifyAll()——>运行

运行——stop()——>消亡

-创建线程的第二种方式(多线程练习2:简单的售票程序(实现多窗口同时售票))

1、自定义类实现Runnable接口

2、覆盖Runnable接口中的run()方法

3、通过Thread类建立线程对象

4、将Runnable接口的子类对象作为参数传递给Thread类的构造函数

5、调用Thread类的start()方法开启线程并调用Runnable接口子类的run()方法。

package day11_Thread;
/**
* 多线程练习2:简单的售票程序(实现多窗口同时售票)
*
* 创建线程的第二种方式:实现Runable接口
* 步骤:
* 		1、自定义类实现Runnable接口
* 		2、覆盖Runnable接口中的run()方法
* 		(将线程要运行的代码存放在该run方法中)
* 		3、通过Thread类建立线程对象
* 		4、将Runnable接口的子类对象作为参数传递给Thread类的构造函数
* 		(将Runnable接口的子类对象传递给Thread的构造函数目的是因为自定义的run()
* 		  方法所属的对象是Runnable接口的子类对象,所以要让线程去指定对象的run()方法,
* 		  必须明确该run()方法所属对象)
* 		5、调用Thread类的start()方法开启线程并调用Runnable接口子类的run()方法
*
* 创建线程的两种方式有什么区别?(***面试考点***)
* 		继承Thread类:线程代码存放在Thread子类run()方法中
* 		实现Runnable接口:线程代码存放在接口子类的run()方法中
* 		实现Runnable接口好处:避免了单继承的局限性(所以建议使用实现方式创建线程)
* @author Administrator
*
*/

class SellTicket1 implements Runnable // extends Thread
{
private int tickets = 100;
//private static int tickets = 100;
public void run(){
while(true){
if(tickets>0){
try {
Thread.sleep(20);//将会出现线程安全问题
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" -// sellTicket: "+tickets--);
}
}
}
}
public class Day11_08_RunnableDemo {

public static void main(String[] args) {

SellTicket1 s = new SellTicket1();

Thread t1 = new Thread(s);
Thread t2 = new Thread(s);
Thread t3 = new Thread(s);
Thread t4 = new Thread(s);

t1.start();
t2.start();
t3.start();
t4.start();

}

}


-创建线程的两种方式有的区别

通过Runnable接口创建线程:

1、可以将cpu,代码和数据分开,形成清晰的模型

2、线程体run()方法所在的类可以从其他类继承一些有用的属性和方法

3、有利 于保持程序设计风格的一致。

直接继承Thread类创建对象:

1、Thread子类无法再从其他类继承(受限于java 语言的单继承模式)

2、编写简单,run()方法的当前对象就是线程对象,可直接操作。实际应用中几乎都是采取第一种方式,因为没有继承的局限性。

实现Runnable接口好处:避免了单继承的局限性(所以建议使用实现方式创建线程)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: