线程-1
1.线程概述
1.1进程
认识进程之前,我们先了解一下程序。 程序(program)是对数据描述与操作的代码的集合。比如office软件。进程(process)是程序的一次执行的过程,它对应了代码的加载,执行至执行完毕的过程。
进程的特点:
1.进程是系统运行程序的基础单位。
2.每一个进程都有自己独立的一块内存空间,一组系统资源。
3.每一个进程的内部数据和状态都是完全独立的。
1.2 线程
线程是进程中运算的最小的单位,可完成一个独立的顺序控制流程。每个进程中,必须至少建立一个线程(这个线程成为主线程)来作为这个程序运行的入口点。如果一个进程中同时运行了多个线程,用来完成不同的工作,则称之为“多线程”。操作系统中将进程分成多个线程后,实际上每个任务是一个线程,多个线程共享相同的地址空间并且共同分享同一进程,这些线程可以在操作系统的管理下并发执行。从而大大提高了程序的运行效率。虽然线程看似是多个线程同时执行,但实际上并非如此。单cpu计算机中,cpu同时只能执行一条指令,因此,在仅一个cpu的计算机上不可能同时执行多个任务。
1.3 多线程的好处
充分利用计算机的资源。
简化编程的模型。
良好的用户体验。
2.在java中实现线程
java在接口和类的方面提供了内置支持,java通过Thread类将线程封装起来。
2.1 Thread 类及常用的方法
构造方法 | 说明 |
---|---|
Thread() | 分配新的Thread() |
boid run() | 执行任务操作的方法 |
void start() | 线程开始执行,Java调用改线程的run()方法 |
void sleep() | 在指定毫秒内让当前的线程休眠 |
String getName() | 返回线程的名称 |
int getPriority | 返回线程的优先级 |
String setName() | 设置线程的名称 |
int setPriority | 设置线程的优先级 |
bollean isAlive() | 测试线程是否活动状态 |
void join() | 等待该进程终止 |
void yield() | 暂停当前正在运行的线程对象,并执行其他线程 |
2.2主线程
在java启动时,一个线程立刻就运行了,该线程通常称为程序的主线程。java程序中的public static void main()方法是主线程的入口,每个进程至少有一个线程。主线程的重要性体现以下两个方面。
1.它是产生其他子线程的线程。
2.通常它必须最后完成执行,因为它执行各种关闭操作。
尽管呢 主线程在启动的时候就自建了,但是我们还是可以由一个thread对象进行控制。
static Thread currentThread()该方法返回一个调用它线程的引用。一旦获得主线程的引用,就可以想控制其它线程那样控制主线程。
示例:
Thread t=Thread.currentThread();
syso("当前线程是"+t.getName());
在该线程中,主线程就是引用currentThread()方法获得的。
2.3继承Thread类创建线程
此线程类需要继承Thread类并重写run()方法。因为run()f方法就是线程要执行操作系统任务的方法,所以线程要执行的代码都要写在run()中,并通过start()方法启动线程。
通过继承写
//重写方法
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+""+i);
}
}
测试类
public static void main(String[] args) {
Test t=new Test();
t.start();
}
注意 已经启动的线程对象不能再次调用star()方法,否则就会有异常。
那么 我们直接调用run方法不好吗?有什么区别呢?
::调用start()方法表示该线程处于启动的状态,等待操作系统的分配资源执行run()方法中的代码,在多个线程同时处于启动状态的时候线程是交替进行的。而直接调用run和之前学的方法没有区别,程序是顺序执行的,属于单线执行模式。
我们可以再创建一个测试类。
Test t=new Test();
Test t1=new Test();
t.start();
t1.start();
结果一部分:
Thread-010
Thread-029
Thread-011
Thread-030
Thread-012
Thread-013
Thread-031
Thread-032
两个线程对象调用start方法后,都会输出100以内的方法相当于每个线程都有自己独立的执行路径,两个分支互不影响,并执行。
所以说线程实例调用start方法和调用run方法是不一样的前者是启动线程,后者是调用实例方法。
2.4 实现Runnable接口创建线程
使用Thread类方法创建线程很简单,但如果定义的类已经继承其他类,则无法继承这个类。所以我们可以使用Runnable接口的方法可以解决上述问题。
Runnable接口 声明了一个抽象方法run(),一个类可以通过实现Runnable接口并实现run()方法完成线程的所有活动,已实现的run()方法称为该线程对象的线程体。任何实现Runnable接口的对象都可以作为一个线程的目标对象。
public static void main(String[] args) {
Test t=new Test();
Thread myThread=new Thread(t);
myThread.start();
}
public class Test implements Runnable{
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName()+""+i);
}
}
}
当一个线程继承了另一个类时,就只能实现Runable接口的方式来创建线程,而且这种方式还可以实现多个线程之间的资源的共享。