线程总结

线程总结


前言:最近学习了一下底层框架的一些技术,学习完之后需要总结一下,总结的可能不太全面,以后会不断修正知识点,学习用博客来总结自己学习是我的第一步。
———————————————————————————————————

1.

首先我先说一下为什么要是用线程:
我们为什么要用线程,因为合理的利用线程,可以减少开发和维护成本,甚至能改善复杂的应用程序的性能,例子有很多:JAVA虚拟机的垃圾回收机制就是很好例子,这个现在不太明白,以后需要用到就会知道了,需要自己体会总结。


2.

什么是线程呢?
官方解释:被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元。 线程简单的理解就是 轻量级进程,多线程就是 同一个应用程序中有多个顺序流同时执行。


3.

怎样去使用,这里我用简单的代码来解释(卖票的一个实例)。
线程有两张方式创建:继承Thread和实现Runnable接口

//继承Thread类
public class Thread_Demo01 extends Thread{
    //定义一个私有常量
    private int tacket=5;
    @Override
    public void run() {
        for(int i=1;i<=5;i++)
        {
            if(tacket>0)
            {
                System.out.println("tacket="+tacket--);
            }
        }
    }
    //创建三个线程
    public static void main(String[] args) {
        new Thread_Demo01().start();
        new Thread_Demo01().start();
        new Thread_Demo01().start();
    }

}
//实现Runnable接口
public class Thread_Demo02 implements Runnable {
    private int stacket = 5;
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            //线程同步 ,判断是否有票
            synchronized (this) {
                if (stacket > 0) {
                    // 线程休眠_毫秒
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    // yield线程礼让
                    if (i == 2) {
                        System.out.println("线程礼让");
                        Thread.currentThread().yield();
                    }
                    System.out.println(Thread.currentThread().getName()
                            + "买票,tacket=" + stacket--);
                }
            }
        }
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        Thread_Demo02 t1 = new Thread_Demo02();
        // 线程优先级设置
        // new Thread(t1).setPriority(Thread.MAX_PRIORITY);
        new Thread(t1).start();
        new Thread(t1).start();
    }
}

4.

观察上面代码你会发现,无论是继承Thread还是实现Runnable接口,都有一个run()方法,线程的运作方式其实是抢占CPU,谁先抢到谁去执行run()方法里的代码片段,抢占方式是随机的。另外你会发现我在实现Runnable接口的列子中用到了其他方法,所以下面我介绍一下继承中经常使用的其他方法:

//返回当前线程
public static Thread currentThread()
//返回线程名字
public final String getName()
//设置线程优先级
public final void setPriority(int priority)
//开始执行线程,使用方式如上
public void start()
//使用目前的线程休眠,使用方式如上
public static void sleep(long m)
//暂停目前的线程,运行其他线程
public final void yield()
//执行线程,此方法并不是真正启动线程,正确方式是调用start()方法
public void run()
---------------------------
//因为是线程内的方法,所以我们在使用的时候是先获取当前线程,再调取线程内的方法,如:
//获取当前线程的名字
Thread.currentThread().getName()

5.

刚才说到线程抢占资源是随机的,但在多线程中也给出了线程的 优先级 设置,如上实例中倒数第三行代码,就是为线程 t1 设置了优先级 ,使用方式如上所示
分为三种:

//最低优先级 表示常量为 1
public static final int MIN_PRIORITY
//中等优先级 表示常量为 5 线程默认优先级
public static final int NORM_PRIORITY
//最高优先级 表示常量为 10
public static final int MAX_PRIORITY

6.

我们线程重不重要,主要看支持线程的地方多不多,下面就要介绍一下 Object类对线程的支持,Object是所有类的父类,所以它的方法使用起来非常方便,线程中所有的对象都可以调用,意义:达到在多线程程序中同步协调资源分配的目的

//线程等待
public final void wait()
//线程等待,并制定等待时间(毫秒)
public final void wait(long timeout)
//唤醒第一个等待线程
public void notify()
//唤醒全部等待的线程
public void notifyAll()

7.

下面我要说的就是线程中最重要的部分了,线程同步,也就是线程安全问题
什么是线程安全呢?举个例子:
一个多个线程程序,(前面介绍过线程执行是随机抢占CPU的)当线程A抢到使用资格后,因为没有同步,在线程A使用过程中,线程B不知道CPU是否空闲,也去使用,这样就会造成混乱,也就是线程安全问题,下面是解决方法
同步方式分为两种,第一种同步代码块,第二种同步方法
同步代码块 在问题3中第二个例子

//两种方法灵活使用
//线程同步 
synchronized (同步对象) {
    //需要同步的代码块
}
//第二种同步方法
synchronized 方法返回类型 方法名(参数列表){

}

8.

死锁问题
经典示例:(代码太多,就不展示了)
爸爸:想要成绩单
儿子:想要玩具
爸爸对儿子说:把考试成绩单给我,就给你玩具
儿子对爸爸说:把玩具给我,就给你考试成绩单
这个问题陷入死循环 也就是死锁问题
产生条件:

  1. 互斥条件:一个资源每次只能被一个线程使用
  2. 请求与保持条件:一个进程因请求资源而阻塞时,对以获得的资源保持不放
  3. 不可剥夺条件:进程已获得的资源,在未使用完之前,不可强行剥夺
  4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

    只要破环死锁4个必要条件中任意一个,死锁问题就能解决


线程的生命周期分别为

  1. 创建状态:
    程序中使用构造方法创建线程对象后,新线程对象即处于创建状态。线程此时已经具有相应的内存空间和其
    他资源,但不可运行。
  2. 就绪状态
    线程对象创建后调用start( )方法启动线程,即进入就绪状态。就绪状态下的线程进入线程队列,等待CPU调
    用。
  3. 运行状态
    线程获得CPU服务后即处于运行状态,此时将自动调用线程对象的run( )方法。run( )方法定义了该线程的具体操作和实现功能。需要注意的是运行状态下的线程调用yield( )方法后,将从运行状态返回至就绪状态。
  4. 阻塞状态
    运行状态的线程调用sleep( )、wait( )等方法后将进入阻塞状态。线程阻塞条件解除后,线程再次转入就绪状态
  5. 终止状态
    当线程执行run( )方法完毕后处于终止状态(又称死亡状态),处于终止状态下的线程不具有继续运行的能力

以上就是线程的基础知识和运用,随着以后工作中使用线程,会不断的积累线程的使用经验,再慢慢深入。

有不对的地方欢迎指正!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值