文章目录
多线程
更多关于多线程的文章链接:
本文有些地方参考了两篇文章。
进程与线程
进程
是静止的,只有真正运行时的程序,才被称为进程。
计算机中的进程:
线程
线程:又称轻量级进程(Light Weight Process)。
- 程序中的一个顺序控制流程,同时也是CPU的基本调度单位。
- 进程由多个线程组成,彼此间完成不同的工作,交替执行,称为多线程。
比如:
- 迅雷是一个进程,当中的多个下载任务即是多个线程。
- Java虚拟机是一个进程,默认包含主线程(main),通过代码创建多个独立线程,与main并发执行
线程的调度
时间片:线程的调度采用时间片轮转的方式
抢占式:高优先级的线程抢占CPU
Java的调度方法:
1.对于同优先级的线程组成先进先出队列(先到先服务),使用时间片策略
2.对高优先级,使用优先调度的抢占式策略
创建线程
创建线程有两种方法
- 继承Thread类
- 实现Runnable接口
继承Thread类
- 定义一个类继承
Thread
,也可以是内部类 - 必须重写
run()
方法 - 在测试类中创建线程对象
- 使用
对象名.start();
方法调用线程 - 注意:一定要
对象名.start()
才能启动线程,无论是哪种创建线程方法,都必须用这条语句
示例:
public class A {
public static void main(String[] args) throws Exception{
Thread.sleep(1000);
Thread thread = new Thread(){
@Override
public void run() {
System.out.println("内部类线程被调用!");
}
};
thread.start();
ATest aTest = new ATest();
Thread thread1 = new Thread(aTest);
thread1.start();
System.out.println("程序结束!");
}
}
public class ATest implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
try {//隔秒输出
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ".............." + i);
}
}
}
线程的常用方法
方法名 | 方法描述 |
---|---|
public static Thread currentThread() | 返回对当前正在执行的线程对象的引用。 |
public static void sleep(long millis) | 使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行) |
public void start() | 导致此线程开始执行; Java虚拟机调用此线程的run方法。结果是两个线程同时运行:当前线程(从调用返回到start方法)和另一个线程(执行其run方法)。 不止一次启动线程是不合法的。 特别地,一旦线程完成执行就可能不会重新启动。 |
public void run() | 如果这个线程是使用单独的Runnable运行对象构造的,则Runnable对象的run方法; 否则,此方法不执行任何操作并返回。 |
public void interrupt() | 中断这个线程。 |
public static boolean interrupted() | 测试当前线程是否中断。 该方法可以清除线程的中断状态 。 换句话说,如果这个方法被连续调用两次,那么第二个调用将返回false(除非当前线程再次中断,在第一个调用已经清除其中断状态之后,在第二个调用之前已经检查过)。 |
public final boolean isAlive() | 测试这个线程是否活着。 如果一个线程已经启动并且尚未死亡,那么线程是活着的。 |
public final void setName(String name) | 将此线程的名称更改为等于参数name 。 首先调用这个线程的checkAccess方法,没有参数。 这可能会导致投掷SecurityException 。 |
public final String getName() | 返回此线程的名称。 |
public final void join(long millis) | 等待这个线程死亡的时间最多为millis毫秒。 0的超时意味着永远等待。 |
public final void setDaemon(boolean on) | 将此线程标记为daemon线程或用户线程。 当运行的唯一线程都是守护进程线程时,Java虚拟机将退出。 |
示例:
测试类A:
package com.wjs.thread;
public class A {
public static void main(String[] args) throws InterruptedException {
ATest aTest = new ATest();
//程序等待1s
Thread.sleep(1000);//直接使用sleep方法需要将异常签名添加到方法名,或者使用try/catch缠绕
//创建3个线程
Thread thread1 = new Thread(aTest,"线程1");
Thread thread2 = new Thread(aTest,"线程2");
Thread thread3 = new Thread(aTest,"线程3");
//启动线程
thread1.start();
thread2.start();
thread3.start();
//线程2等待1秒
thread2.join(1000);
}
}
工具类ATest:
package com.wjs.thread;
public class ATest implements Runnable {
private int ticket = 100;
@Override
public void run() {
//各卖100张
while (true) {
if (ticket < 0) {
break;
}
//Thread.currentThread().getName()-->获取当前进程的名字
System.out.println(Thread.currentThread().getName() + "还有" + ticket + "张票");
ticket--;
}
}
}