深入理解java多线程
进程与线程
一个程序就是一个进程,而一个程序中的多个任务被称之为线程。进程是表示资源分配的基本单位,线程是进程中执行运算的最小单位,亦是调度运行的基本单位。
多线程优缺点
优点:资源利用率更好,程序设计在某些方面更简单,响应更快。
缺点:设计更复杂虽然有一些多线程应用程序比单线程的应用程序要简单,但其他的一般 都更复杂。在多线程访问共享数据的时候,这部分代码需要特别的注意。线程之间的交互往 往非常复杂。不正确的线程同步产 生的错误非常难以被发现,并且重现以修复。
线程的创建与开启
线程的创建:
1、继承Thread类,重写run方法
public class ThreadDemo extends Thread {
@Override
public void run() {
for (int i = 0; i <20 ; i++) {
System.out.println("睡觉");
}
}
}
2、实现Runnable接口重写run方法
class Haha implements Runnable{
@Override
public void run() {
for (int i = 0; i <20 ; i++) {
System.out.println("睡觉");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
3、线程的开启
调用其start()方法
public class ThreadDemo extends Thread {
@Override
public void run() {
for (int i = 0; i <20 ; i++) {
System.out.println("睡觉");
}
}
public static void main(String[] args) {
ThreadDemo threadDemo = new ThreadDemo();
threadDemo.start();
for (int i = 0; i <20 ; i++) {
System.out.println("吃饭");
}
}
}
public class ThreadDemo01 {
public static void main(String[] args) {
Runnable runnable = new Haha();
Thread th = new Thread(runnable);
th.start();
for (int i = 0; i <20 ; i++) {
System.out.println("吃饭");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
线程的五状态模型
创建状态:当new对象时创建线程
就绪状态:start()线程就会进入到就绪状态,线程就会进入就绪队列等待cpu调度
运行状态:cpu把资源分配给这个线程,线程才能进入运行状态,只有从就绪状态才能进入运行状态
阻塞状态:sleep()可以让线程进入阻塞
终止状态:线程结束
线程安全问题
1、多个线程同时操作同一个份资源,才有可能出现线程不安全问题
2、如何控制线程安全问题:
-
synchronized 关键字 控制线程安全--> 控制多个线程排队执行
实现12306买票线程安全问题
public class Web12306 {
int tickes = 100;
public static void main(String[] args) {
//开三个线程进行买票
//使用Lambda表达式
Web12306 web12306 = new Web12306();
Runnable runnable = () -> {
while (web12306.tickes > 0) {
//上锁控制线程安全
synchronized (Web12306.class) {
if (web12306.tickes > 0) {
System.out.println(Thread.currentThread().getName() + "正在买第" + web12306.tickes-- + "张票");
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
//创建并开启进程
new Thread(runnable, "1").start();
new Thread(runnable, "2").start();
new Thread(runnable, "3").start();
}
}