一,多线程概述
1:)进程:通常将一个任务或应用称为一个进程,而一个进程可以包含多个顺序执行流,每个执行流就是一个线程。
2:)线程:应用程序在运行过程中存在着并发执行的多个指令流,每个指令流称为一个线程。
3:)并发:并发并非是同时执行,由于CPU运行快,用时短,所以依然是一个接一个串行执行的。
二,线程创建
线程的创建主要使用继承Thread类和实现Runnable接口。
一,继承Thread类
实现步骤:
1,自定义类,继承Thread类。
2,在类中重写run方法。
3,在调用的位置,实例化线程类的对象,然后调用start方法,启动线程自动执行run方法。
代码演示:线程1
package Test00.Thread;
public class Extends {
//使用继承方式实现多线程
//自定义一个类,然后继承Thread类
public static class ThreadTest extends Thread {
//重写run方法
@Override
public void run(){
for (int i=0;i<50;i++){
System.out.println("学习"+i);
}
}
}
}
线程2
package Test00.Thread;
public class Extends00 {
public static class ThreadTest00 extends Thread{
@Override
public void run() {
for (int i=0;i<50;i++){
System.out.println("玩"+i);
}
}
}
}
实现多线程
package Test00.Thread;
public class Extends01 {
public static void main(String[] args) {
//实例化线程类的对象
Extends00.ThreadTest00 td=new Extends00.ThreadTest00();
Extends.ThreadTest t=new Extends.ThreadTest();
//启动线程
t.start();//自动调用run方法
td.start();
}
}
二,实现Runnable接口
实现步骤
1,自定义类实现Runnable接口。
2,重写run方法,里面放入多线程执行的功能。
3,创建Runnable接口实现类的对象。
4,把Runnable接口实现类的对象作为参数,创建线程对象。
5,线程类对象启动线程----自动调用run方法。
代码演示:
线程1
package Test00.Thread.Test02;
//定义类实现Runnable接口
public class Runnable1 implements java.lang.Runnable {
@Override//重写run方法
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("玩"+i);
}
}
}
线程2
package Test00.Thread.Test02;
public class Runnable2 implements java.lang.Runnable {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
System.out.println("吃"+i);
}
}
}
实现多线程
package Test00.Thread.Test02;
public class Runnable {
//使用接口的方式实现多线程
public static void main(String[] args) {
Runnable1 r1=new Runnable1();//实例化类
Runnable2 r2=new Runnable2();
//创建线程类,将Runnable实例化接口作为参数
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
//启动线程
t1.start();
t2.start();
}
}
总结:
1,继承Thread类的方式适合只需要实现多线程,而无须再继承其他类的时候。
2,实现Runnable接口的方式,更加的灵活,可以实现多线程,同时能够继承别的类。
三,线程间通信
1,概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。
2,作用:多线程的运行过程是随机在各线程之间进行运行的,没有规律可循,而使用线程间通信的方法可以使线程之间的运行可以控制,从而有规律可循。
实现线程间通信需要一种手段即—— 等待唤醒机制。
3,等待唤醒机制
概念:这是多个线程间的一种协作机制。
原理:就是在一个线程进行了规定操作后,就进入等待状态(wait()), 等待其他线程执行完他们的指定代码过后 再将 其唤醒(notify());在有多个线程进行等待时, 如果需要,可以使notifyAll()来唤醒所有的等待线程。
4,注意细节:
二,消费者与生产者模型代码练习(包子,吃货,包子铺):
包子
package Test00.Thread.Test04;
public class BaoZi {
String pier ;
boolean flag = false ;//包子资源 是否存在 包子资源状态
}
吃货
package Test00.Thread.Test04;
public class ChiHuo extends Thread {
private BaoZi bz;
public ChiHuo(String name,BaoZi bz){
super(name);
this.bz = bz;
}
@Override
public void run() {
while(true){
synchronized (bz){
if(bz.flag == false){//没包子
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("吃货正在吃"+bz.pier+"包子");
bz.flag = false;
bz.notify();
}
}
}
}
包子铺
package Test00.Thread.Test04;
public class BaoZiPu extends Thread{
private BaoZi bz;
public BaoZiPu(String name,BaoZi bz){
super(name);
this.bz = bz;
}
@Override
public void run() {
int count = 0;
//造包子
while(true){
//同步
synchronized (bz){
if(bz.flag == true){//包子资源 存在
try {
bz.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 没有包子 造包子
bz.flag=true;
System.out.println("包子造好了:"+bz.pier);
//唤醒等待线程 (吃货)
bz.notify();
}
}
}
}
执行
package Test00.Thread.Test04;
public class Test {
public static void main(String[] args) {
//等待唤醒案例
BaoZi bz = new BaoZi();
ChiHuo ch = new ChiHuo("吃货",bz);
BaoZiPu bzp = new BaoZiPu("包子铺",bz);
ch.start();
bzp.start();
}
}