多线程
1.理解线程的概念
**进程:**一个程序的运行实例,正在运行的程序。通常来说一个程序对应一个进程,它有着独立的内存空间和系统资源。
**线程:**是CPU中运算和分派的基本单位,也是进程中运算的基本单位,一个进程中可以有多个线程。一个线程可以独立完成一个顺序控制流程
多线程和单线程的概念
**单线程:**如果一个程序中只有一个线程,则称为单线程
**多线程:**就是多个线程。
多线程和单线程的区别
- 多线程在执行时并不一定有单线程执行块
- 多线程产生的根本原因也是它的最根本的有事在于我们能够在一个程序中,同事干多件事,可以充分利用CPU资源。
- 其实多线程有两个概念:一种是指单核CPU的多线程,一种是指多核CPU的多线程。
- 单核CPU:同事只能执行一个线程,但是同样可以实现多线程,这个多线程是交替执行的
- 多核CPU:可以进行交替执行,也可以实现真正的物理上的并行执行
主线程
一个进程有且仅有一个主线程,主线程是负责程序的开启和程序最后关闭动作的线程。
java.lang.Thread类
// 获取当前线程 the currently executing thread
Thread currentThread = Thread.currenThread();
// 查看线程的名称
System.out.println(currentThread.getName());
// 设置线程的名称
currentThread,setName("小红");
System.out.println(currentThead.getName());
2.掌握线程的基本创建和启动
线程的第一种创建方式
- 继承Thread类
- 重写run()方法
- 调用start()启动线程
package cn.kga.dome2;
public class My extends Thread {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
if(i == 10) {
try {
Thread.sleep(5000);
}catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("当前执行的线程为:"+Thread.currentThread().getName()+":"+i);
}
}
}
package cn.kga.dome2;
public class Text {
public static void main(String[] args) {
My t1 = new My();
My t2 = new My();
t1.setName("aaa");
t2.setName("bbb");
t1.start();
t2.start();
}
}
线程的第二种创建方式
因为Java是单继承,所以如果你继承了Thread类,呢么未来此类将无法再继承其他的父类
- 实现Runnale接口
- 重写tun()方法
- 创建线程对象 组装Tunnable接口的实现类,调用start()方法启动线程
package cn.kga.dome2;
public class Text {
public static void main(String[] args) {
MyRunnable my = new MyRunnable();
Thread thread = new Thread(my,"dada");
Thread thread2 = new Thread(my,"fafa");
thread.start();
thread2.start();
package cn.kga.dome2;
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
if(i == 10) {
try {
Thread.sleep(5000);
}catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("当前执行的线程为:"+Thread.currentThread().getName()+":"+i);
}
}
}
}
}
start()和run()的区别?
如果是调用run()方法,他只是一个普通方法,届时将只有主线程在执行此方法而已。(和以前的其他方法调用效果无区别)
如果是调用该start()方法,他会新开启一个线程,然后此线程将会和其他线程交替执行某些任务,此线程执行的内容就是run()方法内的任务
3.了解线程的集中状态
创建状态: 当new Thread()时,线程处于创建状态
就绪状态: 当调用start()之后,线程处于就绪状态
运行状态: 当线程分配到了CPU资源,线程处于运行状态,如果线程处于抢占式执行的,方没抢到时,又回到就绪状态。
死亡状态: 当线程执行完任务,或者被外部干涉结束,线程会进入死亡状态
阻塞状态: 当用户在输入\线程在休眠时,线程会进入阻塞状态,当阻塞状态结束后会进入就绪状态。
4.掌握线程调度的常用方法
线程优先级
Thread thread = new Thread(my,"dada");
thread.setPriority(Thread.MAX_PRIORITY);
线程休眠(让这个线程暂时休眠5s,5s之后再次运行)
/ / 括号里面的是表示纳秒,5000==5s
Thread.sleep(5000);
线程礼让
yield();
线程强制执行
// 使当前线程暂停执行,等待其他线程继续执行本线程
xxx.join();
5.掌握线程的同步问题(线程安全)
当我们的程序客流量大的时候,难免会出现安全问题,就比如淘宝店卖卖东西的时候,产品只有100件,但是人数200人抢,就会有安全问题,可能会出现都抢到的情况,会出现负数。这样是不合理的,为了解决这个问题·我们需要一种办法,下面就是其中一种办法。
一. 添加代码块 synchronized
第一种
// 创建一个方法,最后再run()方法里面调用此方法即可
public synchronized void fangfa(){
}
第二种
// 在run()方法里面创建一个构造代码块
synchronized (this) {
}
各位还有其他方法可以在下方评论讨论哦!