继承Thread类
1.创建一个MyThread类继承Thread类
2.在MyThread类中覆写run()方法
3.创建MyThread类的对象
4.启动线程
代码:
class MyThread extends Thread{
@Override
public void run(){
//这里写将要被线程执行的代码
//例:打印1到100
for(int i = 1;i <= 100;i++){
System.out.println(this.getName()+":"i);
//用String getName()获取线程的名称,返回值为String
}
}
}
public class MyThreadDemo{
public static void main(String args[]){
//因为一个MyThread的对象表示一个线程,所以在此实例化两个对象,表示多线程。
MyThread m1 = new MyThread();
m1.setName("线程1");
//setName()设置线程名称,不设置也会有默认的名字,例:Thread-0,Thread-1...
MyThread m2 = new MyThread();
//m1.run(); 这里直接调用run(),线程是不会执行的,需要用start()
//m2.run();
//void start();导致此线程开始执行,然后java虚拟机调用此线程的run方法。
m1.start();
m2.start();
//获取main()方法所在的线程名称:
//通过Thread类的静态方法 static Thread currentThread();返回当前正在执行线程的引用
System.out.println(Thread.currentThread().getName());
}
}
线程调度模型:
1.分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片;
2.抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么会随机选择一个。
优先级高的线程分配的时间片多一些。
Java是抢占式调度模型
多线程程序的执行具有随机性。假设一个计算机只有一个CPU,那么zhegeCPU在某个时刻只能执行一个命令,
线程只有得到CPU的时间片,也就是使用权,才可以执行命令。因为谁抢到的CPU使用权不一定,所有是具有随机性的,
即上方代码运行得到的结果多多少少都有一些不同。(可能有的计算机性能很好,然后在极短时间能执行完,所以得到的结果是一样)
Thread类中设置和获取线程优先级
1.public final int getPriority():返回此线程的优先级;
2.public final void setPriority():更改线程的优先级。
注意:线程优先级的值大只是代表此线程获取CPU时间片的机率大,
并不是先执行完优先级高的线程再执行其他线程。
优先级代码:
public class ThreadPriorityDemo {
public static void main(String[] args) {
ThreadPriority t1 = new ThreadPriority("线程一");
ThreadPriority t2 = new ThreadPriority("线程二");
ThreadPriority t3 = new ThreadPriority("线程三");
// System.out.println(t1.getPriority());
// System.out.println(t2.getPriority());
// System.out.println(t3.getPriority());
//默认的优先级值为5,即Thread.NORM_PRIORITY。最大为10,Thread.MAX_PRIORITY。最小为1,Thread.MIN_PRIORITY。这三个都是Thread类中的静态常量。
//超过这个[1,10]的范围会出现非法参数异常:IllegalArgumentException
t1.setPriority(1);
t2.setPriority(5);
t3.setPriority(10);
//注意:线程的优先级值只是代表此线程获取CPU时间片的几率大,并不是先执行完优先级高的线程再执行其他线程。
t1.start();
t2.start();
t3.start();
}
}
class ThreadPriority extends Thread{
public ThreadPriority(){
}
public ThreadPriority(String name){
super(name);
}
@Override
public void run(){
for(int i = 1; i <= 100;i++){
System.out.println(getName()+":"+i);
}
}
}
线程控制:
| 方法名 | 说明 |
|---|---|
| static void sleep(long millis) | 是当前正在执行的线程停留(暂停执行)指定的毫秒值 |
| void join() | 等待这个线程死亡 |
| void setDaemon(boolean o) | 将此线程标记为守护线程,当守护线程执行完,java虚拟机退出。 |
线程的生命周期:
实现Runnable接口
1.定义一个类MyRunnable实现Runnable接口;
2.重写run()方法;
3.创建MyRunnable对象;
4.创建Thread类的对象,将MyRunnable对象作为构造方法的参数;
5.启动线程。
代码:
public class MyRunnableDemo {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
Thread thread1 = new Thread(mr,"线程一");
Thread thread2 = new Thread(mr,"线程二");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyRunnable implements Runnable{
@Override
public void run(){
for(int i = 1; i <= 100; i++){
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
}
相比继承Thread类,实现Runnable接口的好处 1.避免了java单继承的局限性, 2.适合多个相同的程序代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想。



