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

黑马程序员_<<线程,Thread>>

2013-09-12 09:52 423 查看
--------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流!
--------------------

1.进程

1.概述:
进程就是正在执行的一个程序。可以说是静态的,当进程一旦执行,那么就会在内存中给其分配一定的内存空间,供其运行。
2.从系统上来理解:进程有单进程和多进程
2-1.单进程:就是只能运行一个程序,只有这个程序运行完了,才能运行其他的进程,例如:DOS系统,他的特点就是只要是一种病毒,就会死机,原因就是采用的是单进程
2-2.多进程:就是可以同时运行多个程序,例如现在的Window系统,采用的就是多进程
2-3.Java虚拟机把其封装成了对象,供其使用。
2-4.进程和线程的之间的举例说明:打开qq程序,qq就是一个进程,那么线程就是其中的qq连天窗口。

2. 线程的概述

1.概述:线程是动态的,是进程中的控制单元,一个进程中可以执行多个线程,线程控制着进程。
2.一个进程中至少存在一个线程在执行,
例如:java虚拟机启动后,不只是存在的一个线程,一个是主线程,一个是垃圾回收的线程。
3.线程的执行必须是在有进程的基础之上,当一个线程消失了,那么进程不一定会消失,但是进程消失了,那么线程肯定会消失。
4.主线程:在系统中就是进程一旦创建,就是创建一个线程,那么就是个主线程,那么再有其他的线程生成的话,那就是其子类,在java虚拟机中的主线程是在运行主函数的线程。
5.多线程:多线程会提高执行速度(这只是多线程其中的一个功能例如:下载)当是多线程的话,那么各个线程之间会有优先级。当线程抢到了CPU,谁就会执行。

3. 线程的创建方法

3-1.继承Thread类。

1.定义类继承Thread类。
2.复写run()方法。
3.启动线程,使用start()方法

3-2.实现接口Runnable接口。

1.定义类(A)实现(implements)接口Runnable。
2.重写run()方法。
3.创建线程与类(A)创建联系,开启线程

4. 线程的创建---Thread类

4-1.代码举例

public class MyThread extends Thread {
public void run(){
for(int i=0;i<10;i++)
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
结果:
main--0
Thread-0--0
main--1
Thread-0--1
main--2
Thread-0--2
Thread-0--3
main--3
Thread-0--4
main--4
Thread-0--5
main--5
Thread-0--6
main--6
Thread-0--7
main--7
Thread-0--8
main--8
Thread-0--9
main--9


从结果上可以看出,每次的运行结果都不一样,原因就是自定义的那个线程和主线程抢夺CPU,那一个先抢到CPU,那个就先执行。

4-2.start()和run()的区别和联系

联系:线程调用start()方法实际上是调用的run()方法,run()方法中存储的线程运行的代码
区别:调用start()方法是启动线程,直接调用run()方法的话,那么就和调用普通的方法是一样的,没有启动线程。

public class MyThread extends Thread {
public void run(){
for(int i=0;i<10;i++)
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
public class Text {
public static void main(String[] agrs) {
MyThread tt = new MyThread();
tt.run();
for (int i = 0; i < 10; i++)
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}


这样的话,无论你运行多少次,那么结果都是一样的,因为就存在一个主线程,从结果你就可以看出的。

4-3.复写run()

run() 中存在的是线程运行的代码,对于主线程中运行的代码存储在main()方法中。

4-4.疑问解答

在主线程中,运行时候,也是按照顺序的。直到新的线程开启了,那么才会和存在线程抢夺CPU。

public class MyThread extends Thread {
public void run(){
for(int i=0;i<10;i++)
System.out.println(Thread.currentThread().getName()+"--"+i);
}
}
public class Text {
/*
* 主线程开始从上向下执行,直到执行到了tt线程,启动了tt线程,
* 但是此时主线程已经运行结束了,所以运行结果都是一样的。
* */
public static void main(String[] agrs) {
for (int i = 0; i < 10; i++)
System.out.println(Thread.currentThread().getName() + "--" + i);
MyThread tt = new MyThread();
tt.start();
}
}
public class Text1{
/*
* 主线程开始从上向下执行,开始就创建了线程,并且启动了tt线程,
* 然后tt线程会和主线程抢夺CPU,谁抢到就会执行谁,所以此时运行结果是不确定的
* */
public static void main(String[] agrs) {
MyThread tt = new MyThread();
tt.start();
for (int i = 0; i < 10; i++)
System.out.println(Thread.currentThread().getName() + "--" + i);

}
}


5. 线程状态





6. 线程名称

6-1.默认的线程

默认线程的名称是Thread-0,Thread-2…….。主线程的名称是:main

public class Text {
public static void main(String[] agrs) {
MyThread tt = new MyThread();
System.out.println("默认的线程名称:"+tt.getName());
//tt.start();
System.out.println( "主线程的默认的名字:"+Thread.currentThread().getName());

}
}


6-2.自定义线程

自定义线程名称和获得线程名称名

设置线程名称:可以用setName()方法,可以用构造方法设置线程名称
获得线程名称:用getName()方法获得线程名称
Thread.currentThread()获得当前运行的线程对象

public class MyThread extends Thread {
public MyThread (String name){//通过构造方法设置线程名称
super(name);
}
public void run(){

}
}
public class Text {
public static void main(String[] agrs) {
MyThread tt = new MyThread("线程A");
System.out.println("线程名称:" + tt.getName());
// tt.start();
/*
* 也可以通过setName()来设置线程名称
*/
tt.setName("setName");
System.out.println("线程名称:" + tt.getName());
}
}
结果:
线程名称:线程A
线程名称:setName


7. 售票小例子

public class Tick extends Thread {
private int tick = 10;

public void run() {
while (tick > 0) {
System.out.println(Thread.currentThread().getName() + "卖了第"
+ (tick--) + "张票");
}
}
}
public class Text {
public static void main(String[] agrs) {
new Tick().start();
new Tick().start();//这样相当于开了3个线程,就是3个窗口
new Tick().start();//但是这样相当于各个窗口买各自的票,而不是共享票

}
}


这样的结果相当于买了40张票,但是本来就10张票,重复卖了
结果:
Thread-0卖了第10张票
Thread-2卖了第10张票
Thread-1卖了第10张票
Thread-1卖了第9张票
Thread-2卖了第9张票
Thread-0卖了第9张票
解决办法
1. 把票(tick)定义成静态的,但是如果定义静态的话,但是静态变量声明周期长,不建议这样使用

public class Tick extends Thread {
private static int tick = 10;

public void run() {
while (tick > 0) {
System.out.println(Thread.currentThread().getName() + "卖了第"
+ (tick--) + "张票");
}
}
}


2.可以把值开启一个线程,结果没有错,但是和日常生活多个窗口共同卖票不符合

public class Text {
public static void main(String[] agrs) {
new Tick().start();
}
}


3.使用实现Runnable接口线程处理此情况,最好了。具体的请查看 黑马程序员_<<线程(2)>>

--------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流!
--------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: