首页 > 编程语言 >Java高级06,线程

Java高级06,线程

时间:2024-09-21 16:19:15浏览次数:3  
标签:Java Thread void run 线程 new 06 public

多线程

进程:1. 进程是系统运行程序的基本单位。2. 每一个进程都有自己独立的一块内存空间、一组系统资源。3. 每一个进程的内部数据和状态都是完全独立的。
线程:线程是进程中执行运算的最小单位,可完成一个独立的顺序控制流程。
多线程:一个进程中同时运行多个线程来完成不同的工作。优点:充分利用CPU资源,简化编程膜性,带来良好用户体验。

线程生命周期

创建——就绪——运行——阻塞——死亡
刚new出来时创建状态
调用start()就绪状态
当就绪状态的线程获得CPU资源时,即可转入运行状态,执行run()方法。一个正在运行的线程因某种原因不能继续运行时,进入阻塞状态
一个线程的run()方法运行完毕,则进入死亡状态。处于死亡状态的线程不具有继续运行的能力。

主线程
public class TestMainThread {
    public static void main(String[] args) {
        //获取当前线程
        Thread mainThread = Thread.currentThread();
        //获取线程名字
        String mainName = mainThread.getName();
        System.out.println("线程名字是: " + mainName);
        //设置线程名字
        mainThread.setName("MyMain");
        String newMainName = mainThread.getName();
        System.out.println("修改后线程名字是: " + newMainName);
    }
}

线程创建方式

1.继承Thread类重写run()方法
2.实现Runnable接口,重写run()方法
3.实现 Callable 接口,重写 call 方法,这种方式可以通过 FutureTask 获取任务执行的返回值。

//继承Thread类重写run()方法
public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
    //测试
    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        myThread.start();
    }

//实现Runnable接口,重写run()方法
public class MyRannable implements Runnable{
    @Override
    public void run(){
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
//测试
public static void main(String[] args) {
        MyRannable myRannable = new MyRannable();
        //把创建好的对象传到Thread构造方法中
        Thread thread = new Thread(myRannable);
        thread.start();
        //使用有参构造创建线程
        Thread thread2 = new Thread(myRannable,"newName");
        thread2.start();
    }
}
//实现 Callable 接口,重写 call 方法
public class CallableTest implements Callable<Integer> {
    @Override
    public Integer call(){
        return 10;
    }

public static void main(String[] args) throws ExecutionException, InterruptedException {
    CallableTest callableTest = new CallableTest();
    FutureTask<Integer> futureTask = new FutureTask<Integer>(callableTest);
    Thread thread = new Thread(futureTask);
    thread.start();
    //判断线程是否执行完毕,返回一个boolean值
    futureTask.isDone();
    //获取线程执行完毕后的返回值
    System.out.println(futureTask.get());
}
}
start()和run()区别

线程实例调用start()方法和调用run()方法有着天壤之别,前者是启动线程,后者是调用实例方法。

线程调度

简介:线程调度是指按照特定机制为多个线程分配CU的使用权。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

//join()
public static void main(String[] args) {
        Join join = new Join();
        Thread thread1 = new Thread(join,"线程一");
        thread1.start();
        try {
            //阻塞其他线程,等待自己执行完后,其他线程再执行
            thread1.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    //setPriority()  ,getPriority()
       Thread thread1 = new Thread(join,"first");
       //设置线程优先,参数1-10之间
       thread1.setPriority(10);
        thread1.getPriority();
        }
    //sleep()
     public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println(i+"你好"+Thread.currentThread().getName());
                if(i == 10) {
                    try {
                        //线程休眠
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    //yield()
    public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println(i+"你好"+Thread.currentThread().getName());
                if(i == 10) {
                    try {
                        //线程礼让,释放资源立刻参与争抢
                        Thread.yield();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
/*线程通讯 wait()notify()
    这两个方法是Object类中的方法,用于线程的等待与唤醒,必须搭配synchronized锁使用
    wait()
     wait()让当前执行代码的线程进行等待并主动释放锁,当满足一定条件才会被唤醒重新尝试获取锁
    唤醒wait()?
     1.持有相同对象锁的线程通过对象调用notify()/notifyAll()方法
     2.wait()等待超时,需要提前设置超时时间wait(1000)
    wait()和sleep区别?wait()会释放锁,sleep()不会,wait()来自Object,sleep来自Thread
    notify()
     1.notify()唤醒处于等待中的线程,唤醒与被唤醒线程所使用的锁对象必须是同一个。
     2.执行notify()方法后,线程不会马上释放锁对象而是等到该线程的方法执行完,退出同步代码块才会释放锁
     3.notify()只能随机唤醒一个处于wait()状态的线程,可以使用notifyAll()唤醒所有处于wait()状态的线程*/
//下面两个类示范使用wait()notify()
//一个类M
public class W extends Thread {
    static Object lock = new Object();
    @Override
    public void run() {
        synchronized (lock) {
            while (true) {
                System.out.println("a");
                try {
                    lock.notify();
                    lock.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
//一个类N
public class N extends Thread {
    @Override
    public void run() {
        synchronized (W.lock){
            while (true){
                System.out.println("b");
                try {
                    W.lock.notify();
                    W.lock.wait();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
//测试
public class WandN {
    public static void main(String[] args) {
        W w = new W();
        N n = new N();
        w.start();
        n.start();
    }
}

synchronized

可以用在代码块也能用在方法上

//用在代码块上
public class Gift implements Runnable{
    private static int gif = 0;//送出数量
    private static int count = 100;//剩余数量
    @Override
    public void run() {
        synchronized (this){
            sent();
        }
    }
    public void sent(){
        while(true) {
            if(count > 10){
                gif++;
                count--;
                System.out.println(Thread.currentThread().getName() + "送出了第"+gif+"份礼物剩余"+count+"份");
            }else {
                return;
            }
        }
    }
//用在方法上
public class Gift implements Runnable{
    private static int gif = 0;//送出数量
    private static int count = 100;//剩余数量
    @Override
    public void run() {
            sent();
    }
    public synchronized void sent(){
        while(true) {
            if(count > 10){
                gif++;
                count--;
                System.out.println(Thread.currentThread().getName() + "送出了第"+gif+"份礼物剩余"+count+"份");
            }else {
                return;
            }
        }
    }
Lock

相比于synchronized更加灵活

public class LockThread extends Thread{
    @Override
    public void run() {
        //创建锁
        ReentrantLock lock = new ReentrantLock();
        lock.lock();//上锁
        for (int i = 0; i < 10; i++) {
            System.out.println(i);
            if (i == 5) {
                lock.unlock();
            }
        }
        lock.unlock();//解锁
    }
}

AtomicInteger线程安全的类

AtomicInteger 类是 Java 并发包 (java.util.concurrent.atomic) 中的一个类,用于提供一个整型值的封装,并支持原子操作。它是一个线程安全的类,可以让我们在不需要显式锁的情况下更新整数值。AtomicInteger 内部使用了底层的原子操作来保证其方法的线程安全性。

主要特点

1.线程安全:AtomicInteger 提供的方法都是线程安全的,可以在多个线程之间共享实例而不必担心数据竞争问题。
2.原子性:它的操作如 get()、set()、incrementAndGet()、decrementAndGet() 等都是原子操作,意味着这些操作要么全部完成,要么全部不完成,不会被其他线程中断。

常用方法

get(): 返回当前的整数值。
set(int newValue): 设置当前整数值。
getAndIncrement(): 原子性地将当前值加1,并返回原来的值。
incrementAndGet(): 原子性地将当前值加1,并返回更新后的值。
getAndDecrement(): 原子性地将当前值减1,并返回原来的值。
decrementAndGet(): 原子性地将当前值减1,并返回更新后的值。
compareAndSet(int expect, int update): 如果当前值等于预期值,则以原子方式将该值设置为给定的更新值,并返回 true;否则返回 false。

使用场景

当需要在多线程环境下对某个计数器进行原子性的增减操作时。
需要在不使用锁的情况下实现线程安全的计数器。
当需要实现简单的同步控制逻辑,例如信号量或栅栏等。

标签:Java,Thread,void,run,线程,new,06,public
From: https://blog.csdn.net/m0_72407563/article/details/142419150

相关文章

  • TestNG 与 JUnit:哪种 Java 测试框架适合您?
    测试框架是确保软件质量的重要工具,在Java生态系统中,TestNG和JUnit是最流行的两个选项。虽然这两个框架都有一个共同的目标——让测试变得更容易——但它们提供了不同的特性和功能来满足不同的测试需求。在这篇博文中,我们将深入探讨TestNG与JUnit之间的详细比较,帮助您确定......
  • 1.JDK自带的线程池有哪些?2.线程池中核心线程数与最大线程数与缓冲任务队列的关系?3.为
    1.JDK自带的线程池有哪些?2.线程池中核心线程数与最大线程数与缓冲任务队列的关系?在Java中的线程池(如ThreadPoolExecutor)中,核心线程数(corePoolSize)、最大线程数(maximumPoolSize)以及缓冲队列(workQueue)之间存在着密切的关系,它们共同决定了线程池如何管理和调度任务。以下是......
  • DOM【JavaScript】
    在JavaScript中,DOM(DocumentObjectModel:文档对象模型)是web页面的编程接口,用于表示和操作HTML和XML文档。它将文档结构化为一个树形结构,允许开发者通过JavaScript访问和修改网页的内容、结构和样式。以下是一些关于DOM的关键概念:1.结构DOM树结构是以节点为单位组......
  • 线程(一) 线程的分类、创建、终止
    文章目录线程线程引入进程线程进程和线程的关系进程和线程相比优缺点线程的分类线程的创建线程标识线程创建示例--龟兔赛跑创建线程后内存空间的变化线程终止线程终止后它所占有的资源如何变化示例--线程终止(子线程将普通变量返回给主线程)示例--代码优化(龟兔赛跑)......
  • 2025基于springboot的网上村委会业务办理系统-JAVA.VUE【源码、论文、开题、实训报告
       博主介绍:......
  • 2025基于springboot的自习室管理和预约系统-JAVA.VUE【源码、论文、开题、实训报告】
       博主介绍:......
  • Java毕设常见创新点汇总
    嗨嗨!这里是泡芙,又是新学期开学,部分学校的毕设也是提上日程了,这段时间不少同学在咨询我的过程中,都无外乎表达了这么几点:1、担心自己的项目太过简单过不了期中检查。2、导师提出了必须要加入创新点等要求,为此焦头烂额。3、自己的题目太大众化,不知道怎么避免查重过高。首先,项......
  • java计算机毕业设计教材征订管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景:随着教育事业的蓬勃发展,高校教材管理面临着前所未有的挑战。传统的手工教材征订方式不仅效率低下,且易出错,难以满足日益增长的师生需求及教学管理的精......
  • java计算机毕业设计明德小学教师档案管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着教育信息化步伐的加快,传统的手工管理方式已难以满足明德小学对教师档案管理的需求。教师档案作为学校重要的人力资源信息库,不仅记录了每位教师的......
  • java计算机毕业设计教育培训机构信息管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着教育行业的蓬勃发展,教育培训机构作为知识传播与技能提升的重要平台,其管理效率与服务质量直接关乎学员的学习体验与机构的可持续发展。然而,传统的......