一:多线程的基本概念
线程是进程中的一个执行场景,执行流程。每一个进程是一个应用程序,都有独立的内存空间,同一个进程中的线程共享进程中的内存和资源(堆内存和方法区内存共享,栈内存不共享,每个线程都有自己的)。
问1:计算机引入多进程的作用是什么?引入多线程的作用?
答1:可以提高CPU的使用率。可以提高进程的使用率。
问2:描述java程序的执行原理?(重点!)
答2:Java命令执行会启动JVM(Java虚拟机),JVM的启动表示启动了一个进程。该进程会自动启动一个"主线程",然后主线程负责调用某个类的main方法,main方法是在主线程中执行的,通过main方法代码的执行可以启动其他的"分支线程"。所以main方法结束程序不一定结束。
二:线程的创建与启动
创建线程的方式有两种:
继承Thread类;实现Runnable接口。
方法一:继承Thread类
package 多线程;
public class Thread01 {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start(); //启动分支线程
//执行主线程中的程序
for(int j = 0; j < 100; j++) {
System.out.println("主线程执行--->" + j);
}
}
}
//编写一个类,分支线程
class MyThread extends Thread{
public void run() {
//重写run方法,内容是分支线程
for(int i = 0;i < 100; i++) {
System.out.println("分支线程-->"+ i );
}
}
}
方法二:实现Runnable接口
package 多线程;
public class Thread02 {
public static void main(String[] args) {
Thread t = new Thread(new MyThread2());
for(int j = 0;j<100;j++) {
System.out.print("主线程—>"+ j);
}
}
}
class MyThread2 implements Runnable{
public void run() {
for(int i = 0 ; i< 100;i++) {
System.out.print("分支线程-->"+ i);
}
}
}
三:线程的生命周期
线程的生命周期:新建,就绪,运行,阻塞,死亡。
新建:刚new出来的线程对象t;
就绪:执行t.start()后;处于等待CPU分配资源阶段,有权力抢夺CPU时间片,谁先抢到,谁先执行。
运行:线程被调度并获得CPU时间片时开始运行,run方法定义了线程的操作和功能。
阻塞:由于某些原因(如,执行wait(),sleep()语句)使正在运行的线程变为阻塞状态。需要其他机制将处于阻塞状态的线程唤醒,比如调用notify,唤醒后的线程不会立刻执行run()方法而是到达就绪状态重新抢夺CPU时间片。
死亡:线程退出run()方法。
四:线程的调度与控制
4.1线程优先级、获取当前执行线程对象、修改/获取线程名字
package 多线程;
public class Thread03 {
public static void main(String[] args) {
Thread cur = Thread.currentThread(); //获取当前线程对象
System.out.println(cur.getName()); //输出当前线程对象的名字
MyThread3 t1 = new MyThread3(); //创建分支线程对象t1
MyThread3 t2 = new MyThread3(); //创建分支线程对象t2
t1.setName("aa");//设置t1线程名字
t1.setPriority(MyThread3.MAX_PRIORITY); //设置t1线程最高优先级
t2.setName("bb");
t2.setPriority(MyThread3.MIN_PRIORITY);//设置t2线程最低优先级
t1.start();
t2.start();
}
}
class MyThread3 extends Thread {
public void run() {
for(int i = 0 ; i< 100;i++) {
Thread t = Thread.currentThread(); //获取当前线程对象
System.out.println("当前执行线程为-->:"+t.getName());
}
}
}
4.2 线程睡眠(Thread.sleep,静态方法)
package 多线程;
public class Thread04 {
public static void main(String[] args) {
Thread t1 = new Thread(new MyThread4());
Thread t2= new Thread(new MyThread4());
t1.setName("aa");
t2.setName("bb");
t1.start();
t2.start();
}
}
class MyThread4 implements Runnable{
public void run() {
for(int i = 0 ; i < 100; i++) {
System.out.println("当前线程为"+Thread.currentThread().getName()+','+i);
if (i%10 == 0) {
try {
Thread.sleep(100); //睡眠100毫秒,放取CPU时间片,交给其他线程使用
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
问3:请简述Thread.sleep()和Thread.yield()的区别?
答3:yield()是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。sleep()表示沉睡当前线程。
4.3. t.join()
当前线程可以调用另一个线程的join方法,调用后当前线程会被阻塞不再执行,直到被调用的线程执行完毕,当前线程才会执行。
package 多线程;
public class Thread06 {
public static void main(String[] args) {
Thread t = new Thread(new MyThread06());
t.setName("aa");
t.setPriority(Thread.MAX_PRIORITY);
t.start();
try {
t.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("我是主线程结尾");
}
}
class MyThread06 implements Runnable{
public void run() {
for(int i = 0 ; i< 100;i++) { System.out.println(Thread.currentThread().getName()+"线程正在执行"+i);
}
}
}
4.4 interrupt(中断)
如果线程正在睡眠,可以采用 interrupt 进行中断;
package 多线程;
/*
* sleep睡眠太久了,如果希望半道上醒来,你应该怎么办?
*/
public class ThreadTest07 {
public static void main(String[] args) {
Thread t = new Thread(new MyRunnable2());
t.setName("t");
t.start();
//希望5s后,t线程醒来。
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//中断t线程睡眠(这种中断方式依靠java异常处理机制)
t.interrupt();
}
}
class MyRunnable2 implements Runnable{
//run()当中的异常不能throws,只能try catch
//因为run()方法在父类中没有抛出任何异常,子类不能比父类抛出更多的异常
public void run() {
System.out.println(Thread.currentThread().getName()+"--->"+"begin");
try {
Thread.sleep(1000*60*60*24*365);
} catch (InterruptedException e) {
//打印异常信息
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"--->"+"end");
}
}
参考文献:
Java基础入门 动力节点讲义及老杜课程笔记
本人郑重声明,本博客所著代码、内容版权归权利人持有,本博只做学习交流分享所用,不做任何商业用途。访问者可將本博提供的內容或服务用于个人学习、研究或欣赏,不得用于商业使用。同时,访问者应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人的合法权利;如果用于商业用途,须征得相关权利人的书面授权。若以上代码、内容的原作者不愿意在此展示內容,请即使联系,我将尽快予以刪除。