Java-线程基础知识点总结

本文深入解析了进程和线程的概念,阐述了它们的特点、关系及区别,详细介绍了多线程的实现方式,包括继承Thread类、实现Runnable接口和Callable接口,并探讨了线程的常用方法和生命周期。

第一节、 进程和线程                
                
   1.1 进程(Process)          
    1、 正在运行的程序,是一个程序的运行状态和资源占用(内存,CPU)的描述,通过进程ID区分。            
    2、 进程是程序的一个动态过程,它指的是从代码加载到执行完毕的一个完成过程。            
    3 、目前操作系统支持多进程多任务。            
                
    进程的特点:            
        a.独立性:不同的进程之间是独立的,相互之间资源不共享(举例:两个正在上课的教室有各自的财产,相互之间不共享) 
        b.动态性:进程在系统中不是静止不动的,而是在系统中一直活动的        
        c.并发性:多个进程可以在单个处理器上同时进行,且互不影响        
          
                
   1.2 线程(Thread)                          
    1 线程就是一条执行路径。是进程的组成部分,一个进程可以有多个线程,每个线程去处理一个特定的子任务。

                   
      线程的特点:            
    线程的执行是抢占式的,多个线程在同一个进程中可以并发执行,其实就是CPU快速的在不同的线程之间切换,也就是说,当前运行的线程在任何时候都有可能被挂起,以便另外一个线程可以运行。            
               
    1.3 进程和线程的关系以及区别                
                      
a.一个程序运行后至少有一个进程                
b.一个进程可以包含多个线程,但是至少需要有一个线程,否则这个进程是没有意义的                
c.进程间不能共享资源,但线程之间可以                
d.系统创建进程需要为该进程重新分配系统资源,而创建线程则容易的多,因此使用线程实现多任务并发比多进程的效率高                
 

第二节 多线程的实现                
                
              线程创建方式有三种:                
                
​                   1、 继承Thread类**            
                
​                   2、实现Runnable接口**            
                
​                   3 、实现Callable接口**            
                
  2.1 继承Thread类               
                        
继承自Thread类,Thread类是所有线程类的父类,实现了对线程的抽取和封装                
                
      继承Thread类创建并启动多线程的步骤:                
        a.定义一个类,继承自Thread类,并重写该类的run方法,该run方法的方法体就代表了线程需要完成的任务,因此,run方法的方法体被称为线程执行体        
        b.创建Thread子类的对象,即创建了子线程        
        c.用线程对象的start方法来启动该线程        
注意: 1 、程序运行时会自动创建一个线程 ,这个线程叫主线程;可以通过主线程创建子线程。                
             2 、启动线程使用start()方法,不要直接调用run()方法。      

 2.2 实现Runnable接口                 
                     
      实现Runnable接口创建并启动多线程的步骤:                
                
        a.定义一个Runnable接口的实现类,并重写该接口中的run方法,该run方法的方法体同样是该线程的线程执行体        
        b.创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象        
        c.调用线程对象的start方法来启动该线程  

      实现Runnable接口的例子:

        模拟实现四个窗口售票功能。

        一、实现Runnable接口:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Ticket implements  Runnable{
   private int ticket=1000;
    Lock lock =new ReentrantLock();
    @Override
    public void run() {
        while (true){
            lock.lock();
            try {
                if (ticket<1){
                break;
            }else{
            System.out.println(Thread.currentThread().getName()+"卖了第"+ticket+"张票");
            ticket--;
                }
            } finally {
               lock.unlock();
            }

        }

        }
    }

         二。编写测试类
         

public class Test {
    public static void main(String[] args) {
        //创建票对象
        Ticket ticket=new Ticket();
        //创建线程
        Thread w1=new Thread(ticket, "窗口1");
        Thread w2=new Thread(ticket, "窗口2");
        Thread w3=new Thread(ticket, "窗口3");
        Thread w4=new Thread(ticket, "窗口4");
        //启动线程
        w1.start();
        w2.start();
        w3.start();
        w4.start();

    }
}

    2.3 两种实现方式的比较             
                
            1、 继承Thread类的方式                
                 a.没有资源共享,编写简单 如果要访问当前线程,除了可以通过Thread.currentThread()方式之外,还可以使用getName()     获取线程名字。            
                 b.弊端:因为线程类已经继承了Thread类,则不能再继承其他类【单继承】            
            2、 实现Runnable接口的方式                
                 a.可以多个线程共享同一个资源,所以非常适合多个线程来处理同一份资源的情况            
                 b.资源类实现了Runnable接口。如果资源类有多个操作,需要把功能提出来,单独实现Runnable接口。            
                 c.弊端:编程稍微复杂,不直观,如果要访问当前线程,必须使用Thread.currentThread()            
                
             总结:实际上大多数的多线程应用都可以采用实现Runnable接口的方式来实现【推荐使用匿名内部类】                 

    2.4 调用start()与run()方法的区别            
     
         **  当调用start()方法时将创建新的线程,并且执行run()方法里的代码,但是如果直接调用run()方法,不会创建新的线程。           2.5 线程的第三种创建方式:                 
       使用Callable接口实现多线程 :Callable 有返回值,可以跑出异常。

   调用: 1、创建可调用对象   2、创建一个任务    3、创建线程    4、启动线程    5、获取返回值。

 例子:

public class MyCallable implements Callable <Integer>{

    @Override
    public Integer call() throws Exception {
        int sum=0;
        for (int i = 0; i <=100; i++) {
            sum+=i;
            Thread.sleep(3000);
            System.out.println(i);
        }

        return sum;
    }
}

           测试类:

public class Test {
    public static void main(String[] args) throws  Exception{
        //  创建可调用对象
        MyCallable callable=new MyCallable();
        //创建任务
        FutureTask<Integer> task=new FutureTask<>(callable);
        //创建线程
      Thread thread=new Thread(task);
        //启动
        thread.start();
        // 获取
          Integer d=task.get();
        System.out.println(d);

    }
}

第三节   线程的常用方法  

      3.1  线程休眠:使得当前正在执行的线程休眠,释放时间片,进入阻塞状态。

        Thread.sleep(1000);    //  相当于当前线程挂起1s。

      3.2  设置线程优先级: 优先级高的线程获得较多的执行机会。

       ***     优先级范围: 1-10   默认为 5      对应值越大,说明优先级越高,这个方法的设置一定在start()之前。

      3.3  合并(加入)线程: 阻塞当前线程,知道加入的线程执行完毕,才继续执行。

       ***    join之前一定要将线程处于准备状态 (start)。

      3.4   后台线程(守护线程): 隐藏起来默默运行的线程,例如jvm。

              特征: 如果所有的前台线程都死亡,后台线程自动死亡。

             设置后台线程:  demoThread.setDaemon(true);

      3.5  线程让步:  yield  (虚伪的让步)    让出CPU的使用权,让出后还参与争夺。只让给优先级和它相同或者优先级比它高的。       Thread.yield(); 

      3.6  线程中段 :  程序在等待的过程中可以使用 interrupt 方法来打断。

 第四节 线程的生命周期       

                   新生--->就绪---->运行---->阻塞----->死亡     
                    
      对于线程,当线程被创建,进入新生状态,调用start()方法 ,进入就绪状态(可执行状态),如果抢到cpu,进入运行状态,运行过程中出现了阻塞,进入阻塞状态,如果程序正常结束进入死亡状态。        
            
            New(新生):线程被实例化,但是还没有开始执行            
            Runnable(就绪):没有抢到时间片            
            Running(运行):抢到了时间片,CPU开始处理这个线程中的任务            
            Blocked(阻塞):    线程在执行过程中遇到特殊情况,使得其他线程就可以获得执行的机会,被阻塞的线程会等待合适的时机重新进入就绪状态        
            Dead(死亡):线程终止            
                          a.run方法执行完成,线程正常结束【正常的死亡】        
                          b.直接调用该线程的stop方法强制终止这个线程        
              
                  State枚举表示线程的状态(六种)            
                           NEW (新生)        
                           RUNNABLE  (可运行、运行)        
                           BLOCKED (锁阻塞)        
                           WAITING  (等待)        
                           TIMED_WAITING  (限时等待)sleep(5000)        
                           TERMINATED (终止死亡)        
        
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值