Java多线程知识点总结,超详细代码!(一)

一:多线程的基本概念

线程是进程中的一个执行场景,执行流程。每一个进程是一个应用程序,都有独立的内存空间,同一个进程中的线程共享进程中的内存和资源(堆内存和方法区内存共享,栈内存不共享,每个线程都有自己的)。
问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基础入门 动力节点讲义及老杜课程笔记

本人郑重声明,本博客所著代码、内容版权归权利人持有,本博只做学习交流分享所用,不做任何商业用途。访问者可將本博提供的內容或服务用于个人学习、研究或欣赏,不得用于商业使用。同时,访问者应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人的合法权利;如果用于商业用途,须征得相关权利人的书面授权。若以上代码、内容的原作者不愿意在此展示內容,请即使联系,我将尽快予以刪除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值