多线程
学习目标
进程特点
1.进程是系统运行程序的基本单位
2.每个进程都有自己独立的一块内存空间,一组系统资源
3.每一个进程的内部数据和状态都是完全独立的
线程
线程是进程内部的一个执行单元,是可完成一个独立的任务的顺序控制流程
多线程
什么是多线程
如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为“多线程”
多个线程交替占用CPU资源,而非真正的并行执行
多线程好处
充分利用CPU的资源
简化编程模型
带来良好的用户体验
线程分为;核心级线程 用户级线程
编写线程类
主线程;
每个程序中至少自动拥有一个线程,称为主线程,当程序加载到内存时启动主线程,java程序中的main()方法是主线程的入口,运行java程序时,会先执行main()方法。
开发中,用户编写的线程一般都是指除了主线程之外的其他线程
使用线程步骤;
1.定义一个线程,同时指明这个线程所要执行的代码,即期望完成的功能
1.继承Thread类 2.实现Runnable接口
2.创建线程对象
3.启动线程
对象.start()
4.终止线程
public static void main(String[] args) {
//获得主线程对象
Thread t=Thread.currentThread();
// System.out.println(t.getName());
//设置主线程名
t.setName("my java thread");
//获取当前线程名
System.out.println(t.getName());
}
继承Thread类创建线程
重写run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程
package H2.p5练习;
//继承Thread创建线程
public class ThreadText2 extends Thread{
public void run(){
Thread t=new Thread();
t.setName("线程");
for (int i = 0; i < 100; i++) {
System.out.println(t.getName()+":"+i );
}
}
public static void main(String[] args) {
ThreadText2 t2=new ThreadText2();
//启动线程
t2.start();
}
}
CPU决定
多个线程交替执行,不是真正的“并行”
线程每次执行时长由分配的CPU时间片长度决定
public static void main(String[] args) {
ThreadText2 t2=new ThreadText2();
ThreadText2 t3=new ThreadText2();
t2.start();
t3.start();
}
实现Runnable接口创建线程
实现run()方法,编写线程执行体
创建线程对象,调用start()方法启动线程
package H2.p5练习;
//实现Runable接口创建线程
public class MyRunable implements Runnable{
public void run() {
Thread t=new Thread();
t.setName("线程");
for (int i = 0; i < 100; i++) {
System.out.println(t.getName()+";"+i);
// System.out.println(Thread.currentThread().getName()+";"+i);
}
}
public static void main(String[] args)throws Exception {
MyRunable my=new MyRunable();
Thread t=new Thread(my);
Thread t1=new Thread(my);
t.start();
t1.start();
}
}
线程的4种状态
新生状态
可运行状态
阻塞状态
死亡状态
线程优先级
线程优先级由1~10表示,1最低,默认优先级为5
优先级高的线程获得CPU资源的概率较大
package H2.p5练习;
//实现Runable接口创建线程
public class MyRunable implements Runnable{
int count=0;
public void run() {
for (int i = 0; i < 100; i++) {
//System.out.println(t.getName()+";"+i);
//System.out.println(t1.getName()+";"+i);
System.out.println(Thread.currentThread().getName()+";"+i);
count++;
System.out.println("count值;"+count);
}
}
public static void main(String[] args)throws Exception {
//MyRunable my=new MyRunable();
//创建线程对象并指定线程名
Thread t=new Thread(new MyRunable(),"线程A");
Thread t1=new Thread(new MyRunable(),"线程B");
//最高优先级
t.setPriority(Thread.MAX_PRIORITY);
//最低优先级
t1.setPriority(Thread.MIN_PRIORITY);
t.start();
t1.start();
}
}
线程休眠
让线程暂时睡眠指定时长,线程进入阻塞状态
睡眠时间过后线程会再进入可运行状态
public void run(){
Thread t=new Thread();
t.setName("线程");
for (int i = 0; i < 100; i++) {
try {
//设置休眠
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(t.getName()+":"+i );
}
线程的强制运行join()
public static void main(String[] args)throws Exception {
//MyRunable my=new MyRunable();
Thread t=new Thread(new MyRunable(),"线程A");
Thread t1=new Thread(new MyRunable(),"线程B");
t.setPriority(Thread.MAX_PRIORITY);
t1.setPriority(Thread.MIN_PRIORITY);
for (int i=0;i<100;i++){
if (i==10){
t1.start();
t1.join();
}
}
t.start();
在这里插入代码片package H2.p5练习;
//模拟看病叫号
public class CallText implements Runnable {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("特需号;"+(i+1)+"病人在看病");
}
}
public static void main(String[] args) {
Thread thread = new Thread(new CallText());
thread.setPriority(Thread.MAX_PRIORITY);
for (int i = 0; i < 50; i++) {
System.out.println("普通号:"+(i+1)+"号病人在看病!");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}if (i==9){
try {
thread.start();
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}