A:如何实现多线程:
如何实现呢?
由于线程是依赖进程而存在的,所以我们应该先创建一个进程出来。
而进程是由系统创建的,所以我们应该去调用系统功能创建一个进程。
但是Java是不能直接调用系统功能的,所以,我们没有办法直接实现多线程程序。
但是呢?Java可以去调用C/C++写好的程序来实现多线程程序。
由C/C++去调用系统功能创建进程,然后由Java去调用这样的东西,
然后提供一些类供我们使用。我们就可以实现多线程程序了。
参考 Thread类
B:多线程程序实现的方式1
a:继承Thread类
b:步骤及代码演示
c:几个小问题:
启动线程使用的是那个方法
线程能不能多次启动
run()和start()方法的区别
我们启动线程使用不是run方法,而应该是start方法.使该线程开始执行;
Java 虚拟机调用该线程的 run 方法。
为什么要重写run方法?
这个类是一个线程类,那么在这个类中我们可不可以写一些其他的方法呢?
我们可以在写其他的方法,那么其他方法中封装的代码都是需要被我们线程执行的吗? 不一定
那么也就是run方法中封装应该是必须被线程执行的代码.
run方法中的代码的书写原则: 一般是比较耗时的代码
C:案例演示: 多线程程序实现的方式1
public class MyTest {
public static void main(String[] args) {
MyTread myTread = new MyTread();
myTread.start();
}
}
public class MyTread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
}
多线程(获取和设置线程对象名称)
A:Thread类的基本获取和设置方法
public final String getName()//获取线程名称
public final void setName(String name)//设置线程名称
其实通过构造方法也可以给线程起名字
思考:
如何获取main方法所在的线程名称呢?
public static Thread currentThread()//获取当前执行的线程
/**
* 我们现在是想获取主线程的名称,那么我们可不可以先获取到主线程,
如果我们能获取到主线程,那么我们就可以调用getName方法获取对应的名称.
* 如何获取主线程呢? public static Thread currentThread()返回对当前正在执行的线程对象的引用。
*/
B:案例演示: 获取和设置线程对象名称
public class MyTest {
public static void main(String[] args) {
Thread mainTread = MyTread.currentThread();
String name = mainTread.getName();
System.out.println("主线程执行了"+name);
MyTread myTread = new MyTread();
MyTread myTread1 = new MyTread();
myTread.setName("一");
myTread1.setName("二");
myTread.start();
myTread1.start();
}
}
public class MyTread extends Thread{
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.getName()+"=="+i);
}
}
}
多线程(线程调度及获取和设置线程优先级)
A:线程的执行
假如我们的计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,
线程只有得到 CPU时间片,也就是使用权,才可以执行指令。那么Java是如何对线程进行调用的呢?
B:线程有两种调度模型:
分时调度模型 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
抢占式调度模型 优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
Java使用的是抢占式调度模型。
C:如何设置和获取线程优先级
public final int getPriority() //获取线程的优先级
public final void setPriority(int newPriority)//设置线程的优先级
D:案例演示: 获取和设置线程优先级
public class MyTest {
public static void main(String[] args) {
Thread th1 = new MyThread("一");
Thread th2 = new MyThread("二");
th1.setPriority( Thread.MAX_PRIORITY);
th2.setPriority( Thread.MIN_PRIORITY);
int priority1 = th1.getPriority();
int priority2 = th2.getPriority();
System.out.println(priority1);
System.out.println(priority2);
th1.start();
th2.start();
}
}
public class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.getName()+"=="+i);
}
}
}
注意事项: 有的时候我们给线程设置了指定的优先级,但是该线程并不是按照优先级高的线程执行,那是为什么呢?
- 因为线程的优先级的大小仅仅表示这个线程被CPU执行的概率增大了.但是我们都知道多线程具有随机性,
- 所以有的时候一两次的运行说明不了问题
/**
* 我们现在呢没有给线程设置优先级,那么java采用的是抢占式调度模型,那么这个线程应该存在一个默认的优先级.
* 那么这个默认的优先级是多少呢,以及我们如何来获取线程的优先级.
* 获取线程的优先级:
* public final int getPriority()返回线程的优先级。
* 线程的默认优先级是5
*
* 给线程设置优先级:
* public final void setPriority(int newPriority)
*/
多线程(线程控制之休眠线程)
A:线程休眠: public static void sleep(long millis) 线程休眠
B:案例演示: 线程休眠
public class MyTest {
public static void main(String[] args) {
MyThread th1 = new MyThread("线程A");
th1.start();
}
}
public class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 100; i++) {
System.out.println(this.getName()+"=="+i);
}
}
}
多线程(线程控制之加入线程)
A:加入线程: public final void join()
意思就是: 等待该线程执行完毕了以后,其他线程才能再次执行
注意事项: 在线程启动之后,在调用方法
B:案例演示: 加入线程
public class MyTest {
public static void main(String[] args) throws InterruptedException {
MyThread th1= new MyThread("刘备");
MyThread th2= new MyThread("张飞");
MyThread th3= new MyThread("关羽");
th1.start();
th1.join();
th2.start();
th3.start();
th3.join();
}
}
public class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.getName()+"=="+i);
}
}
}
多线程(线程控制之礼让线程)
A:礼让线程: public static void yield(): 暂停当前正在执行的线程对象,并执行其他线程。
B:案例演示: 礼让线程
public class MyTest4 {
public static void main(String[] args) {
MyThread th1 = new MyThread("线程一");
MyThread th2 = new MyThread("线程二");
th1.start();
th2.start();
}
}
public class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
Thread.yield();
for (int i = 0; i < 100; i++) {
System.out.println(this.getName()+"=="+i);
}
}
}
按照我们的想法,这个礼让应该是一个线程执行一次,但是通过我们的测试,效果好像不太明显.
那是为什么呢?
这个礼让是要暂停当前正在执行的线程,这个暂停的时间是相当短的,如果在这个线程暂停完毕以后,其他的线程还没有抢占到CPU的执行权,那么这个时候这个线程应该再次和其他线程抢占CPU的执行权.
多线程(线程控制之守护线程)
A:守护线程: public final void setDaemon(boolean on):
将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。
该方法必须在启动线程前调用。
B:案例演示: 守护线程
public class MyTest5 {
public static void main(String[] args) {
Thread.currentThread().setName("主线程:李世民");
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
MyThread th1 = new MyThread("李建成");
MyThread th2 = new MyThread("李元吉");
th1.setDaemon(true);
th2.setDaemon(true);
th1.start();
th2.start();
}
}
public class MyThread extends Thread{
public MyThread() {
}
public MyThread(String name) {
super(name);
}
@Override
public void run() {
for (int i = 0; i < 300; i++) {
System.out.println(this.getName()+"=="+i);
}
}
}