1、线程的创建和启动
- Java语言的JVM允许程序运行多个线程,它通过java.lang.Thread类来体现。
Thread类的特性
Thread():创建新的Thread对象
- Thread(String threadname):创建线程并指定线程实例名
- Thread(Runnabletarget):指定创建线程的目标对象,它实现了Runnable接口中的run方法
Thread(Runnable target, String name):创建新的Thread对象
3、API创建线程的两种方式
JDK1.5之前创建新执行线程有两种方法:
- 创建一个继承于Thread类的子类
- 重写Thread的run()方法 —-> 将此线程的方法声明在run()方法中
- 创建Thread的子类对象
- 通过此对象调用start() ```java package com.haiyang.java;
/**
- 多线程的创建 方式一: 继承于 Thread类
- 1、创建一个继承于Thread类的子类
- 2、重写Thread类的run()方法
- 3、创建Thread类的子类对象
- 4、通过此对象调用start() *
- 例子: 遍历100以内的所有偶数
*/
public class ThreadTest {
public static void main(String[] args) {
}//3、创建Thread子类的对象MyThread myThread = new MyThread();//4、调用start()方法myThread.start();
} //1、创建一个继承Thread类的子类 class MyThread extends Thread{ //2、重写Thread类的run()方法
@Overridepublic void run() {for (int i = 0; i < 100; i++) {if (i % 2 == 0){System.out.println(i);}}}
}
<a name="BaQNW"></a>### 3.1.1、Thread中常用的方法- **start()**: 启动当前线程,调用当前线程的run()方法- **run()**:通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中- **currentThread()**:静态方法,返回执行当前代码的线程- **getName()**:获取当前线程的名字- **setName()**:设置当前线程的名字- **yield() **:释放当前cpu的执行权- **join()**: 在线程a中调用线程b的join(),此时线程a就会进入阻塞状态,直到线程b完全执行完成以后,线程a才结束阻塞状态- **stop()**: 已过时 当执行此方法时强制线程结束- **sleep(long millitime) **: 让当前线程“睡眠"指定的millitime毫秒,在指定睡眠的时间内,当前线程处于阻塞状态- **isAlive() **: 判断当前线程是否存活<br />```java/**** 测试 Thread中常用的方法* 1、start(): 启动当前线程,调用当前线程的run()方法* 2、run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中* 3、currentThread():静态方法,返回执行当前代码的线程* 4、getName():获取当前线程的名字* 5、setName():设置当前线程的名字* 6、yield() :释放当前cpu的执行权* 7、join(): 在线程a中调用线程b的join(),此时线程a就会进入阻塞状态,直到线程b完全执行完成以后,线程a才结束阻塞状态* 8、stop(): 已过时 当执行此方法时强制线程结束* 9、sleep(long millitime) : 让当前线程“睡眠"指定的millitime毫秒,在指定睡眠的时间内,当前线程处于阻塞状态* 10、isAlive() : 判断当前线程是否存活* @author 杨磊* @create 2021-09-24 20:12*/public class ThreadMethodTest {public static void main(String[] args) {//通过构造器给线程取名HelloThread ht = new HelloThread("Thread:1");//ht.setName("线程1");//给主线程命名Thread.currentThread().setName("主线程");ht.start();for (int i = 0; i < 100; i++) {if (i % 2 == 0){System.out.println(Thread.currentThread().getName() + ":" + i);//yield(); 释放线程的执行权}if (i == 20){try {ht.join();} catch (InterruptedException e) {e.printStackTrace();}}}}}class HelloThread extends Thread{public HelloThread(String name){super(name);}@Overridepublic void run() {for (int i = 0; i < 100; i++) {try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ":" + i);//yield(); 释放线程的执行权}}}
3.1.2、线程的调度
- 调度策略
- 时间片

抢占式:高优先级的线程抢占CPU
Java的调度方法
MAX_PRIORITY:10 —->最高优先级
- MIN _PRIORITY:1 —->最低优先级
-
3.1.2.2、涉及到的方法
getPriority() :返回线程优先值
setPriority(intnewPriority) :改变线程的优先级
说明:
高优先级的线程要抢占低优先级线程cpu的执行权。
- 但是只是从概率上讲,高优先级的线程高概率的情况下被执行。
并不意味着只有当高优先级的线程执行完以后,低优先级的线程才会被执行。
3.2、创建多线程的方式二:
创建一个实现了Runnable接口的类
- 实现类去实现Runnable中的接口方法
- 创建实现类对象
- 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
- 通过Thread类的对象调用start() ```java package com.haiyang.java;
/**
- 创建多线程的方式二 : 实现Runnable接口
- 1、创建一个实现了Runnable接口的类
- 2、实现类去实现Runnable中的接口方法
- 3、创建实现类对象
- 4、将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
- 5、通过Thread类的对象调用start()
- @author 杨磊
- @create 2021-09-24 22:04
*/
//1、创建一个实现了Runnable接口的类
class MThread implements Runnable{
//2、实现类去实现Runnable中的接口方法
@Override
public void run() {
} } public class ThreadTest1 { public static void main(String[] args) {for (int i = 0; i < 100; i++) {if (i % 2 == 0 ){System.out.println(i);}}
} }//3、创建实现类对象MThread mThread = new MThread();//4、将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象Thread th = new Thread(mThread);//5、通过Thread类的对象调用start()th.start();Thread th2 = new Thread(mThread);th2.start();
<a name="zJqqh"></a>## 3.3、继承方式和实现方式的联系与区别开发中:优先选择:实现Runnable接口的方式<br />原因:- 实现的方式没有类的单继承性的局限性- 实现的方式更适合来处理多个线程有共享数据的情况。联系:public class Thread implements Runnable<br />相同点:两种方式都需要重写run(),将线程要执行的逻辑声明在run()中<a name="pJWNH"></a># 4、补充:线程的分类**Java中的线程分为两类:一种是守护线程,一种是用户线程。**- 它们在几乎每个方面都是相同的,唯一的区别是判断JVM何时离开。- 守护线程是用来服务用户线程的,通过在start()方法前调用**thread.setDaemon(true)**可以把一个用户线程变成一个守护线程。- Java垃圾回收就是一个典型的守护线程- 若JVM中都是守护线程,当前JVM将退出。- 形象理解:兔死狗烹,鸟尽弓藏<a name="s3DG4"></a># 练习1```java/*** 例子: 创建三个窗口去买票,总票数为100张* @author 杨磊* @create 2021-09-24 21:36*/class Window extends Thread{private static int ticket = 100;@Overridepublic void run() {while (true){if (ticket > 0){System.out.println(getName() + "卖票,票号为:" + ticket);ticket--;}else {System.out.println("不好意思,已经没有票了");break;}}}}public class WindowTest {public static void main(String[] args) {Window w1 = new Window();Window w2 = new Window();Window w3 = new Window();w1.setName("窗口1");w2.setName("窗口2");w3.setName("窗口3");w1.start();w2.start();w3.start();}}
