进程:是一个正在执行的程序。
每一个进程执行都有一个执行顺序。该顺序是一个路径,或者叫一个控制单元
线程:就是进程中的一个独立的控制单元。
线程控制着进程的执行。
一个进程中至少有一个线程。
Java VM 启动的时候会有一个进程java.exe.
该进程中至少有一个Java程序的执行。
执行的代码在mian方法中。
该线程称之为主线程。
扩展:还有一个负责垃圾回收机制的线程。
一,实现多线程的方法:
实现的方法一:
1, 继承Thread类
2, 复写run()方法
3, 创建对象调用start方法
该方法两作用:启动线程,调用run方法
在某一时刻,只能运行一个程序(多核除外)。同时运行的效果是cup在不短的切换
4,常用方法:static Thread currentThread()获取当前线程对象
getName();获取线程的名称
设置线程的名称:构造函数或者setName()
实现的方法二:
1,实现Runnable接口。
2,复写Runnable接口中的run方法
将运行的代码写在run方法中
3,创建Runnable接口的子类对象
4,创建Thread类的对象并把Runnable接口的子类对象作为参数传递给Thread的构造函数。
为什么要传递?
因为自定义的run方法属于Runnable接口的子类对象所以要让
线程去执行指定的对象的run方法,就必须明确该run方法所属的对象
5,调用Thread的start方法开启线程并执行Runnable接口子类中复写的run方法。
实现和继承的区别:
避免单继承的局限
两种方式的区别:
存放代码位置不同:Thread子类run方法中
Runnable接口子类run方法中
为什么要复写run方法?
用于存储要执行的代码
run()方法 和start()方法的区别
调用run方法只仅仅调用方法
调用start方法开启线程并调用run方法
线程的四种状态:
创建,运行,冻结,消亡,(特殊状态:阻塞 在运行和冻结之间)
线程会出现共享数据发生错误:
解决办法:同步代码块
synchronized(对象){
需要同步的代码
}
同步的前提: 1,多个线程同时运行 2,多个线程用同一个锁;
同步的好处:提高多线程的安全性
同步的弊端:要判断锁比较消耗资源
同步函数用的锁是this(静态函数的锁是该类的字节码文件对象) 同步代码块用的锁是对象
死锁:
class Test1 implements Runnable{
private boolean flag;
Test1(boolean flag){
this.flag = flag;
}
public void run(){
if(flag){
synchronized (MyLack.la) {
System.out.println("if la");
System.out.println("if la");
synchronized (MyLack.lb) {
System.out.println("if lb");
}
}
}else{
synchronized (MyLack.lb) {
System.out.println("else lb");
synchronized (MyLack.la) {
System.out.println("else la");
}
}
}
}
}
class MyLack{
static Object la = new Object();
static Object lb = new Object();
}
public class LackTest {
public static void main(String args[]){
Thread t1 = new Thread(new Test1(true));
Thread t2 = new Thread(new Test1(false));
t1.start();
t2.start();
}
}
|
|