线程相关知识学习-Java基础学习总结

本文详细阐述了进程与线程的概念,对比了两者的区别,深入讲解了Java中线程的创建方法,包括继承Thread类、实现Runnable接口及Callable接口。此外,还探讨了线程的生命周期、线程安全问题及其解决方案,以及死锁现象的产生和避免。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程,进程相关概念

进程

进程:正在运行的应用程序,一个电脑可以有多个进程,但在某一时刻/时间点(单核)CPU只能执行一个进程;CPU可以在多个进程间进行高速转换;

线程
  • 线程:依赖于进程,进程开启后,会执行很多的任务,而将每个任务,称之为线程
  • 线程具有随机性,会去抢占CPU的执行权,谁获得CPU的执行权,谁执行;但每一时刻只能执行一个线程
  • 进程是拥有资源,且CPU执行的是线程
  • 进程是拥有资源的基本单位,线程是CPU调度的基本单位。
单线程、多线程还境浅层概述
  • 单线程环境:只有一条执行路径
  • 多线程环境:具有多条执行路径
多线程意义
  • 提高应用程序的使用率,提高CPU利用率。
多线程并发与并行
  • 多线程并发:指在某一时刻同时运行多个程序;
  • 多线程并行:指在某一时间段内同时运行多个程序;

Java中如何开启一个线程

方法一:

  1. 继承Thread类;
  2. 重写Thread类中run()方法;
  3. 调用start()方法,开启线程;
继承Thread类:
public class myThread extends Thread {
   @Override
   public void run() {
       for (int i = 0; i < 100; i++) {
           System.out.println(i);
       }
   }
}
开启线程:
public class test {
   public static void main(String[] args) {
       myThread myThread = new myThread();
       myThread.start();
   }
}

方法二:

  1. 实现Runnable接口;
  2. 重写接口中的run()方法;
  3. 建立Runnable接口子对象,将其作为参数传进Thread的构造方法中,建立Thread类对象;
  4. 调用start()方法,开启线程;
实现接口:
public class myThread1 implements Runnable {
    @Override
    public void run() {
        System.out.println("我进来了!");
    }
}
开启线程:
public class test1  {
    public static void main(String[] args) {
        myThread1 myThread1 = new myThread1();
        Thread thread = new Thread(myThread1);
        thread.start();
    }
}

方法三:

  1. 实现Callable接口;
  2. 重写接口中的call()方法(注此方法具有返回值,有需求可以使用方法三);
  3. 建立Callable接口子对象,将其作为参数传进FutureTask的构造方法中,建立FutureTask子对象,将其作为参数传进Thread的构造方法中,建立Thread类对象;
  4. 调用start()方法,开启线程;
实现接口:
    public class myThread2 implements Callable {
    @Override
    public Object call() throws Exception {
        System.out.println("我又进来了");
        return null;
    }
} 
开启线程:
public class test2 {
    public static void main(String[] args) {
        myThread2 myThread2 = new myThread2();
        FutureTask<Object> task = new FutureTask<Object>(myThread2);
        Thread thread = new Thread(task);
        thread.start();
    }
} 

线程的相关方法

  • getName() // 获取线程名
  • setName(String name) //重置新的线程名
  • currentThread()//获取当前执行的线程
  • currentThread().getName() //获取当前执行的线程名
  • getPriority() //获取线程的优先级
  • setPriority(int newPriority)//设置线程的优先级(参数范围1-10)
    注:建立线程的优先级的大小仅仅表示这个线程被CPU执行的概率增大了.但是多线程具有随机性,所以效果不是很明显,且线程的默认优先级是5
  • sleep(long millis) // 线程休眠(也就是暂停millis毫秒后,在执行后面代码,调用方式为Thread.sleep(1000) )
  • join() // 使线程串行运行,即一个运行完后,其他在运行
    注: 在线程启动之后,在调用方法
  • yield(): // 暂停当前正在执行的线程对象,并执行其他线程;调用格式为:Thread.yield()(理想化状态)
  • setDaemon(boolean on) //将该线程标记为守护线程或用户线程。
    注:当主线程运行完后,守护线程随之停止,该方法必须在启动线程前调用。
守护线程代码演示:
  myThread myThread = new myThread();
        myThread.setDaemon(true);
        myThread.start();
        System.out.println("我真的疯了");
        System.out.println("我真的疯了");
        System.out.println("我真的疯了");
        System.out.println("我真的疯了");
        System.out.println("我真的疯了");
  • stop(): // 停止线程的运行
  • interrupt(): // 中断线程的阻塞状态

线程的安全性问题、解决方法

  • 形成安全问题,需满足条件
1.	多线程
2.	多线程存在并发操作共享数据
3.	多条语句操作共享数据
  • 解决方法

方法一: 使用同步代码块
格式:
synchronized(锁){
有可能出错的代码;
}
注:此时的锁,是任意类型的对象

代码演示
     synchronized (Bianliang.obja) {
               System.out.println("true"+Bianliang.obja+"进来了");
           }

方法二: Lock锁
ReentrantLock类中的 lock() //加锁 ,unlock() //去掉锁
格式:
ReentrantLock lock = new ReentrantLock();
lock.lock();
有可能出错的代码;
lock.unlock();
注:此方法最好放在try,catch,finally中,确保锁的释放

同步代码块、同步方法、同步静态方法锁对象的类型
  • 同步代码块:任意对象
  • 同步方法:this
  • 静态同步方法:就是当前类对应的字节码文件对象(如:Thread.class)

死锁概述、实现

概述:是指两个或者两个以上的线程在执行的过程中,因争夺资源产生的一种互相等待现象(如果出现了同步嵌套,就容易产生死锁问题)

### 同步嵌套实现
public class myThread extends Thread {
    boolean flag;
    public myThread(boolean s) {
       this.flag=s ;
    }
 @Override
    public void run() {
      /*  ReentrantLock lock = new ReentrantLock();   
        lock.lock();
        lock.unlock();*/
        if(flag){
            synchronized (Bianliang.obja){
                System.out.println("true"+Bianliang.obja+"进来了");
                synchronized (Bianliang.objb){
                    System.out.println("true"+Bianliang.objb+"进来了");
                }
            }
        }else{
            synchronized (Bianliang.objb){
                System.out.println("false"+Bianliang.objb+"进来了");
                synchronized (Bianliang.obja){
                    System.out.println("false"+Bianliang.obja+"进来了");
                }
            }
        }
    }
}
### 线程开启
public class test {
    public static void main(String[] args) {
        myThread thread1 = new myThread(true);
        myThread thread2 = new myThread(false);
        thread1.start();
        thread2.start();
    }
}
### 相关变量声明
public class Bianliang {
    static Object obja =new Object();
    static Object objb =new Object();
}

案例实现(多线程实现多窗口卖票)
### 继承Thread类,重写run方法
public class myThread extends Thread {
    static int  i=1000;  //票数
    Object obj = new Object (); //同步代码块中的锁

    public myThread(String s) {
        super (s);
    }
    @Override
    public void run() {
        while (true){
            synchronized (obj){
                if(i>=1){
                    System.out.println(this.getName()+"正在出售第"+(i--)+"张票");
                }else{
                    break;
                }
            }
        }
    }
}
### 线程开启
public class test {
    public static void main(String[] args) {
        myThread thread1 = new myThread("窗口一");  
        myThread thread2 = new myThread("窗口二");   
        myThread thread3 = new myThread("窗口三");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值