黑马程序员--多线程概述和常见问题
2014-06-19 20:22
351 查看
------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------
谈到线程,不得不先要理解什么是进程。进程是一个正在执行中的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫做一个控制单元。线程(Thread)就是进程中的一个独立的控制单元,线程在控制着进程的执行。一个进程中至少有一个线程,即至少有一个控制单元。
Java虚拟机启动时会有一个进程java.exe,该进程中至少一个线程负责java程序的执行, 而且该线程称之为主线程。需要强调的是JVM在启动时不止有一个进程,还有负责
垃圾回收机制的线程。
如何在自定义的代码中,自定义一个线程 呢?线程存在于某一个进程当中,进程是系统创建的,所以Java中已经提供了此类事物的体现,java.lang包中有一个Thread类。
创建线程的一种方式就是:
1. 定义类继承Thread类
2. 重写(覆盖)Thread中的run( )方法。目的是:将自定义的代码存储在run方法中,让线程运行
3. 调用线程的start( )方法。 该方法有两个作用:启动线程,调用run()方法
示例代码1:
package com.itheima.day11;
class Demoextends Thread{
public void run(){
for (int x = 0; x < 500; x++) {
System.out.println("demo run---"+x);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
//继承完之后,创建对象,即创建好了一个线程
Demo d =
new Demo();
//开启线程并执行该线程的run()方法,start是调用的底层,让控制台执行的动作
d.run();
for (intx = 0; x < 500; x++) {
System.out.println("Hello World!--"+x);
}
}
}
发现:
每一次的运行结果都不同,因为多个线程都在获取CPU的执行权,CPU执行到哪个进程的线程,就会执行哪一个进程
明确一点:在某一时刻,只能有一个程序在运行(多核除外)
原理:
CPU在做着快速的切换,以达到看上去同时运行的效果
这就是多线程的一个特性:随机性(哪个程序抢到CPU资源,它就会执行,执行多长时间,由CPU决定)
事实:
Windows本身是一个多任务操作系统,表面看似在同时执行多个程序,其实,CPU在某一个时间内只能执行一个程序,它是在多个程序之间进行快速的切换,速度非常之快,所以会认为是同时执行,其实是在切换每一个进程中的线程,若一个进程中有多个线程,CPU也在进行切换,这就是为什么同一时间内开的程序越多,电脑就会运行的
越慢(多个线程在抢夺CPU资源,但是是有CPU决定的),但是若为双核,多核,就能够实现同时执行,双核多核
以后内存就是 瓶颈,临时存储空间要足够大,双核标配内存要在2G以上
run( )和start( )的特点:
Thread类用于描述线程,该类定义了一个功能,即run()方法,用于存储线程要运行的代码。
主线程运行的代码,存储在main()方法中,这是由JVM定义的,这就是虚拟机调用main()方法的原因
因为是主线程在调用.Java中规定了自定义的线程的代码,存储在Thread的run()方法中 start()调用的是 Thread类
所属对象的run()方法,要沿袭父类功能,重写父类内容
调用start()和run() 的不同 :
A. d.start();--->开启线程并执行该线程的run()方法,start是调用的底层,让控制台执行的动作.打印结果是
交替打印
B. d.run();---->仅仅是对象调用方法,而线程创建了,并没有执行.(仅仅是封装了线程要运行的代码).打印结果是
先将run中封装的代码执行完之后再执行start的代码,没有启动主线程
创建线程的第二种方式:实现Runnable接口
步骤:
1. 定义类实现Runnable
2. 覆盖Runnable接口中的run()方法
3. 通过 Thread类创建线程对象
4. 将Runnable接口的子类对象传递给Thread类的构造函数
为什么要将Runnable接口的子类对象传递给Thread的构造函数呢?
因为,自定义的run()方法所属的对象是Runnable接口的子类对象
所以要让线程指定对象的run()方法,就必须明确该run方法所属对象
5. 调用Thread类的start()方法,开启线程并调用Runnable接口子类的run()方法
实现方式和继承方式有什么不同呢?
实现方式好处:避免了单继承的局限性
在定义线程时,建议使用实现方式
存放线程代码位置不同:
继承Thread:线程代码存放在Thread子类的run()方法中
实现Runnable,线程代码存放在接口的子类run()方法中
注意:
Thread类本身也实现Runnable接口,Runnable的定义其实就是在确线程运行代码所存放的位置
示例代码2:
package com.itheima.day11;
class
Ticket1 implements Runnable{
private int
tick = 100;
public void run(){
while(true){
if(tick>0){
System.out.println(Thread.currentThread().getName()+" sale:"+tick--);
}
}
}
}
public class ThreadRunnableDemo {
public static void main(String[] args) {
Ticket1 t = new Ticket1();
//创建了一个线程
Thread t1 =
new Thread(t);
Thread t2 =newThread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
/**
* 分析:
*作用是开启线程,调用的是Thread类中的run()方法,但是此时的Ticket3实现的是
*Runnable接口,其中也有run方法,此时Thread中的run()中没有卖票的代码
*/
t1.start();
t2.start();
t3.start();
t4.start();
}
}
谈到线程,不得不先要理解什么是进程。进程是一个正在执行中的程序。每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫做一个控制单元。线程(Thread)就是进程中的一个独立的控制单元,线程在控制着进程的执行。一个进程中至少有一个线程,即至少有一个控制单元。
Java虚拟机启动时会有一个进程java.exe,该进程中至少一个线程负责java程序的执行, 而且该线程称之为主线程。需要强调的是JVM在启动时不止有一个进程,还有负责
垃圾回收机制的线程。
如何在自定义的代码中,自定义一个线程 呢?线程存在于某一个进程当中,进程是系统创建的,所以Java中已经提供了此类事物的体现,java.lang包中有一个Thread类。
创建线程的一种方式就是:
1. 定义类继承Thread类
2. 重写(覆盖)Thread中的run( )方法。目的是:将自定义的代码存储在run方法中,让线程运行
3. 调用线程的start( )方法。 该方法有两个作用:启动线程,调用run()方法
示例代码1:
package com.itheima.day11;
class Demoextends Thread{
public void run(){
for (int x = 0; x < 500; x++) {
System.out.println("demo run---"+x);
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
//继承完之后,创建对象,即创建好了一个线程
Demo d =
new Demo();
//开启线程并执行该线程的run()方法,start是调用的底层,让控制台执行的动作
d.run();
for (intx = 0; x < 500; x++) {
System.out.println("Hello World!--"+x);
}
}
}
发现:
每一次的运行结果都不同,因为多个线程都在获取CPU的执行权,CPU执行到哪个进程的线程,就会执行哪一个进程
明确一点:在某一时刻,只能有一个程序在运行(多核除外)
原理:
CPU在做着快速的切换,以达到看上去同时运行的效果
这就是多线程的一个特性:随机性(哪个程序抢到CPU资源,它就会执行,执行多长时间,由CPU决定)
事实:
Windows本身是一个多任务操作系统,表面看似在同时执行多个程序,其实,CPU在某一个时间内只能执行一个程序,它是在多个程序之间进行快速的切换,速度非常之快,所以会认为是同时执行,其实是在切换每一个进程中的线程,若一个进程中有多个线程,CPU也在进行切换,这就是为什么同一时间内开的程序越多,电脑就会运行的
越慢(多个线程在抢夺CPU资源,但是是有CPU决定的),但是若为双核,多核,就能够实现同时执行,双核多核
以后内存就是 瓶颈,临时存储空间要足够大,双核标配内存要在2G以上
run( )和start( )的特点:
Thread类用于描述线程,该类定义了一个功能,即run()方法,用于存储线程要运行的代码。
主线程运行的代码,存储在main()方法中,这是由JVM定义的,这就是虚拟机调用main()方法的原因
因为是主线程在调用.Java中规定了自定义的线程的代码,存储在Thread的run()方法中 start()调用的是 Thread类
所属对象的run()方法,要沿袭父类功能,重写父类内容
调用start()和run() 的不同 :
A. d.start();--->开启线程并执行该线程的run()方法,start是调用的底层,让控制台执行的动作.打印结果是
交替打印
B. d.run();---->仅仅是对象调用方法,而线程创建了,并没有执行.(仅仅是封装了线程要运行的代码).打印结果是
先将run中封装的代码执行完之后再执行start的代码,没有启动主线程
创建线程的第二种方式:实现Runnable接口
步骤:
1. 定义类实现Runnable
2. 覆盖Runnable接口中的run()方法
3. 通过 Thread类创建线程对象
4. 将Runnable接口的子类对象传递给Thread类的构造函数
为什么要将Runnable接口的子类对象传递给Thread的构造函数呢?
因为,自定义的run()方法所属的对象是Runnable接口的子类对象
所以要让线程指定对象的run()方法,就必须明确该run方法所属对象
5. 调用Thread类的start()方法,开启线程并调用Runnable接口子类的run()方法
实现方式和继承方式有什么不同呢?
实现方式好处:避免了单继承的局限性
在定义线程时,建议使用实现方式
存放线程代码位置不同:
继承Thread:线程代码存放在Thread子类的run()方法中
实现Runnable,线程代码存放在接口的子类run()方法中
注意:
Thread类本身也实现Runnable接口,Runnable的定义其实就是在确线程运行代码所存放的位置
示例代码2:
package com.itheima.day11;
class
Ticket1 implements Runnable{
private int
tick = 100;
public void run(){
while(true){
if(tick>0){
System.out.println(Thread.currentThread().getName()+" sale:"+tick--);
}
}
}
}
public class ThreadRunnableDemo {
public static void main(String[] args) {
Ticket1 t = new Ticket1();
//创建了一个线程
Thread t1 =
new Thread(t);
Thread t2 =newThread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
/**
* 分析:
*作用是开启线程,调用的是Thread类中的run()方法,但是此时的Ticket3实现的是
*Runnable接口,其中也有run方法,此时Thread中的run()中没有卖票的代码
*/
t1.start();
t2.start();
t3.start();
t4.start();
}
}
相关文章推荐
- 23 API-多线程(多线程概述,多线程实现方案,线程控制常见方法,线程安全问题及解决)
- 黑马程序员------多线程(No.1)(概述、线程的创建、安全问题、同步锁、同步函数)
- 黑马程序员——多线程比较常见而且比较重要的问题
- 黑马程序员---java多线程的一些常见问题
- 黑马程序员——多线程——多线程概述,实现,控制与安全问题的解决
- 编写多线程Java应用程序常见问题
- (转帖)使用多线程编程的几个常见问题- -
- 多线程程序设计常见问题
- 黑马程序员_常见java问题小计
- 黑马程序员——多线程操作经典实例:生产者消费者问题
- 黑马程序员---多线程的几个小问题
- 黑马程序员-ASP.NET多线程问题
- 编写多线程Java应用程序常见问题
- 【转】并发危险:解决多线程代码中的 11 个常见的问题
- 并发危险:解决多线程代码中的 11 个常见的问题(C#示例) from MSDN
- 编写多线程的Java应用程序-如何避免当前编程中最常见的问题
- 编写多线程Java应用程序常见问题
- 解决多线程代码中的11个常见问题[详细/经典]
- 黑马程序员_常见java问题小计
- 黑马程序员-java 常见问题【个人总结】