javaAPI_多线程基础_多线程基础1
Posted 德墨特尔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javaAPI_多线程基础_多线程基础1相关的知识,希望对你有一定的参考价值。
多线程基础1
1.如何实现多线程?
由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来。
而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。
Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序。
但是呢?Java可以去调用C/C++写好的程序来实现多线程程序。
由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西,
然后提供一些类供我们使用。我们就可以实现多线程程序了
通过查看API,我们知道了有2中方式实现多线程程序
2.创建线程的方式1:继承Thread类
(1).步骤:
A:自定义类MyThread继承Thread类。
B:MyThread类里面重写run()?
为什么是run()方法呢?
C:创建对象
D:启动线程
(2).为什么在继承Thread的方法的时候需要重写run()方法呢?
不是类中的所有代码都需要被线程执行的。
而这个时候,为了区分哪些代码能够被线程执行,java提供了Thread类中的run()用来包含那些被线程执行的代码.
(3).哪一些代码适合加入到线程中呢?
一般来说,被线程执行的代码肯定是比较耗时的
(4).一个多线程实现的基本代码:
//线程类
public class MyThread extends Thread {
@Override
public void run() {
for (int x = 0; x < 200; x++) {
System.out.println(x);
}
}
}
//测试类
public static void main(String[] args) {
// 创建两个线程对象
MyThread my1 = new MyThread();
MyThread my2 = new MyThread();
my1.start();
my2.start();
}
(5).相关注意事项
面试题:run()和start()的区别?
run():仅仅是封装被线程执行的代码,直接调用是普通方法
start():首先启动了线程,然后再由jvm去调用该线程的run()方法。
(6).异常
IllegalThreadStateException:非法的线程状态异常
为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。也就是说同一个线程不可以被启动俩次。
3.多线程的基本操作_获取线程名称
(1).获取线程对象的名称
public final String getName():获取线程的名称。
(2).设置线程对象的名称
public final void setName(String name):设置线程的名称
(3).针对不是Thread类的子类中如何获取线程对象名称呢?
public static Thread currentThread():返回当前正在执行的线程对象
Thread.currentThread().getName()
(4).基本功能相关测试
//多线程类
public class MyThread extends Thread {
public MyThread() {
}
public MyThread(String name){
super(name);
}
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x);
}
}
}
//测试类
public static void main(String[] args) {
// 创建线程对象
//无参构造+setXxx()
// MyThread my1 = new MyThread();
// MyThread my2 = new MyThread();
// //调用方法设置名称
// my1.setName("张三");
// my2.setName("李四");
// my1.start();
// my2.start();
//带参构造方法给线程起名字[这里面需要在多线程类中添加带参构造方法传入到其父类中去]
// MyThread my1 = new MyThread("张三");
// MyThread my2 = new MyThread("李四");
// my1.start();
// my2.start();
//我要获取main方法所在的线程对象的名称,该怎么办呢?
//遇到这种情况,Thread类提供了一个很好玩的方法:
//public static Thread currentThread():返回当前正在执行的线程对象
System.out.println(Thread.currentThread().getName());
}
4.线程调度以及设置线程的优先级
(1).线程调度的意义
假如我们的计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到 CPU时间片,也就是使用权,才可以执行指令。
(2).线程调度的俩种模型
A:分时调度模型
所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
B:抢占式调度模型
优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
Java使用的是抢占式调度模型。
(3).获取线程对象的优先级
public final int getPriority():返回线程对象的优先级
(4).如何设置线程对象的优先级呢?
public final void setPriority(int newPriority):更改线程的优先级。
注意:
线程默认优先级是5。
线程优先级的范围是:1-10。
线程优先级高仅仅表示线程获取的 CPU时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到比较好的效果。
(5).代码:
public static void main(String[] args) {
ThreadPriority tp1 = new ThreadPriority();
ThreadPriority tp2 = new ThreadPriority();
ThreadPriority tp3 = new ThreadPriority();
tp1.setName("东方不败");
tp2.setName("岳不群");
tp3.setName("林平之");
// 获取默认优先级
// System.out.println(tp1.getPriority());
// System.out.println(tp2.getPriority());
// System.out.println(tp3.getPriority());
// 设置线程优先级--IllegalArgumentException:非法参数异常。
// tp1.setPriority(100000);
//设置正确的线程优先级
tp1.setPriority(10);
tp2.setPriority(1);
tp1.start();
tp2.start();
tp3.start();
}
//多线程执行的代码
public class ThreadPriority extends Thread {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x);
}
}
}
5.线程控制之休眠线程
(1).相关方法
public static void sleep(long millis):让线程休眠指定时间
(2).代码体现
//线程类
public class ThreadSleep extends Thread {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x + ",日期:" + new Date());
// 睡眠
// 困了,我稍微休息1秒钟
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//测试类
public static void main(String[] args) {
ThreadSleep ts1 = new ThreadSleep();
ThreadSleep ts2 = new ThreadSleep();
ThreadSleep ts3 = new ThreadSleep();
ts1.setName("张三");
ts2.setName("李四");
ts3.setName("王五");
ts1.start();
ts2.start();
ts3.start();
}
6.线程控制之加入线程
(1).相关方法
public final void join():等待该线程终止。也就是存在着先后顺序,先有父后有子
(2).相关代码
//线程类
public class ThreadJoin extends Thread {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x);
}
}
}
//测试类
public static void main(String[] args) {
ThreadJoin tj1 = new ThreadJoin();
ThreadJoin tj2 = new ThreadJoin();
ThreadJoin tj3 = new ThreadJoin();
tj1.setName("李渊");
tj2.setName("李世民");
tj3.setName("李元霸");
tj1.start();
try {
tj1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
tj2.start();
tj3.start();
}
6.线程控制之礼让线程
(1).相关方法
public static void yield():暂停当前正在执行的线程对象,并执行其他线程。在一定程度上可以保证程序的执行更和谐一些。
但是无法保证每一个线程执行一次。
(2).相关代码
//线程类
public class ThreadYield extends Thread {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x);
Thread.yield();
}
}
}
//测试类
public static void main(String[] args) {
ThreadYield ty1 = new ThreadYield();
ThreadYield ty2 = new ThreadYield();
ty1.setName("林青霞");
ty2.setName("刘意");
ty1.start();
ty2.start();
}
7.线程控制之守护线程[也叫后台线程]
(1).相关方法
public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程。
当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。
(2).代码测试
//线程类代码
public class ThreadDaemon extends Thread {
@Override
public void run() {
for (int x = 0; x < 100; x++) {
System.out.println(getName() + ":" + x);
}
}
}
//测试类代码
public static void main(String[] args) {
ThreadDaemon td1 = new ThreadDaemon();
ThreadDaemon td2 = new ThreadDaemon();
td1.setName("关羽");
td2.setName("张飞");
// 设置收获线程[守护刘备,for循环结束以后,后面的线程不再执行]
td1.setDaemon(true);
td2.setDaemon(true);
td1.start();
td2.start();
Thread.currentThread().setName("刘备");
for (int x = 0; x < 5; x++) {
System.out.println(Thread.currentThread().getName() + ":" + x);
}
}
7.线程控制之中断线程[*****]
(1).相关方法
public final void stop():让线程停止,过时了,但是还可以使用。
public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException。
(2).测试代码
//线程类代码
public class ThreadStop extends Thread {
@Override
public void run() {
System.out.println("开始执行:" + new Date());
// 我要休息10秒钟,亲,不要打扰我哦
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// e.printStackTrace();
System.out.println("线程被终止了");
}
System.out.println("结束执行:" + new Date());
}
}
//测试类代码
public static void main(String[] args) {
ThreadStop ts = new ThreadStop();
ts.start();
// 你超过三秒不醒过来,我就干死你
try {
Thread.sleep(3000);
// ts.stop();过时,但是不建议使用
ts.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
8.线程的生命周期
以上是关于javaAPI_多线程基础_多线程基础1的主要内容,如果未能解决你的问题,请参考以下文章