cpu拿到执行权执行应用程序
1. 什么是应用程序?
可以执行的软件,QQ、YY等
在一个应用程序中,都会有一个进程
2. 什么是进程?
进程中有多个不同的执行路径
多个线程的集合
进程是执行中的程序
一个操作系统可以有多个进程
3. 在进程中,程序代码是如何执行的?
代码的执行顺序是靠的哪个进程?
在进程中,一定有一个线程,这个线程是主程序(main)
4. 什么是线程?
一个执行顺序,一个执行流程、执行路径。
比如:一个迅雷软件肯定会有一个进程,你点击迅雷打开软件就执行了该进程的主线程,如果你同时下载几个资源,这些下载资源的行为都算一个线程,彼此互不影响。
总结:
使用多线程,可提高程序效率,每个线程互不影响,因为彼此独立运行。
什么是进程,进程就是正在运行的程序,它是线程的集合。
什么是线程,就是正在独立运行的一条执行路径。
什么是多线程,为了提高程序的效率。
5. 线程实现的几种方式
a. 继承Thread
b. 实现Runnable接口
c. 使用匿名内部类
d. 实现Callable接口
e. 使用线程池实现
6. 线程常用接口
Thread.start()
Thread.sleep()
Thread.currentThread()
//不建议使用stop()
Thread thread=new Thread(t1,"子线程"); 为线程命名
7. 守护线程和非守护线程
用户自定义的线程叫用户线程,主线程停止掉,不会影响用户线程
除了主线程之外,还有一个线程是gc线程
gc线程不定时回收垃圾,主线程死了,gc线程也会销毁,gc线程主要是回收主线程的垃圾
守护线程特征:和主线程一起销毁
非守护线程特征:和主线程互不影响
8. 多线程的运行状态
//新建状态
Thread t1=new Thread();
//就绪状态
t1.start();
//运行状态
t1.run();
//阻塞状态
Thread.sleep(0);
//死亡状态,run()执行完后
9. join()方法
A线程调用B线程join()方法表示 A等B线程执行完过后再继续执行
可实现三个线程按照顺序执行
public class ThreadDemo3 {
public static void main(String[] args) {
Thread t1=new Thread(new Runnable() {
@Override
public void run() {
System.out.println("a");
}
});
Thread t2=new Thread(new Runnable() {
@Override
public void run() {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("b");
}
});
Thread t3=new Thread(new Runnable() {
@Override
public void run() {
try {
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("c");
}
});
t1.start();
t2.start();
t3.start();
}
}
10. 什么是线程安全问题?
当多个线程共享同一个全局变量,写操作时,可能会受到其他线程干扰,导致数据有问题。
读操作肯定是不会出现线程安全问题的
解决办法
synchronized ----自动档
lock ----jdk1.5并发包 ---- 手动档
class ThreadTrain1 implements Runnable{
private int trainCount=100;
@Override
public void run() {
while (trainCount>0){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
sale();
}
}
//同步函数 使用的this锁
public synchronized void sale(){
if(trainCount>0){
System.out.println(Thread.currentThread().getName()+",出售第"+(100-trainCount+1)+"票");
trainCount--;
}
}
}
public class ThreadDemo4 {
public static void main(String[] args) {
ThreadTrain1 threadTrain1=new ThreadTrain1();
Thread t1=new Thread(threadTrain1,"窗口1");
Thread t2=new Thread(threadTrain1,"窗口2");
t1.start();
t2.start();
}
}
代码块实现同步 使用的对象锁(object)
public void sale(){
synchronized (object){ //只有一个线程能访问,必须拿到锁才能访问
if(trainCount>0){
System.out.println(Thread.currentThread().getName()+",出售第"+(100-trainCount+1)+"票");
trainCount--;
}
}
}
静态同步函数不使用this锁 用当前字节码文件为锁 参数:eg:Test.class
public static synchronized void sale(){
if(trainCount>0){
System.out.println(Thread.currentThread().getName()+",出售第"+(100-trainCount+1)+"票");
trainCount--;
}
}
11. 使用同步的条件
a. 必须要有两个线程以上
b. 多个线程想同步,必须用同一把锁
c. 保证只有一个线程进行执行。
原理:
1.有一个线程拿到锁,其他正在执行的线程排队等待其释放锁。
2.锁什么时候释放呢? 线程执行的代码执行完毕或者抛出异常都会被释放掉。
3.锁被释放后,其他线程就行竞争,然后获得权限开始执行。
缺点:
效率非常低,时刻要判断锁,进行抢锁
ps: 单纯记录自己所学记录------------仅供参考