Java多线程不会?一文解决——

方法一

  1. 新建类如MyThread继承Thread类
  2. 重写run()方法
  3. 再通过new MyThread类来新建线程
  4. 通过start方法启动新线程

案例:

java 复制代码
class MyThread extends Thread {
    public MyThread(String name) {
        super(name);
    }
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            System.out.println(this.getName() + " " + i );
        }
    }

}

主类:
          MyThread myThread1 = new MyThread("Thread-1");
          MyThread myThread2 = new MyThread("Thread-2");
          MyThread myThread3 = new MyThread("Thread-3");
          myThread1.start();
          myThread2.start();
          myThread3.start();

常用方法

  • static void sleep(T):让当前线程睡T毫秒
  • static void yield():当前线程从运行变为就绪状态,重新争夺cpu
  • void run():执行线程中run()方法(在当前线程中执行)
  • void start():开启一个新的线程执行run()方法
  • void setName():设置这个线程的名称
  • String getName():获取当前线程的名称
  • void interrupt():中断执行的子线程
  • void join():等该线程执行完后,再执行当前线程

例:

当前主线程需等待t01,t02,t03线程执行完后再执行。


方法二

  1. 创建新类MyThread实现Runnable接口
  2. 实现接口中的run方法
  3. 创建MyThread对象,再新建Thread对象,将MyThread对象作为构造方法的参数传入Thread
  4. 通过start方法启动新的线程

案例:

java 复制代码
class MyThread implements Runnable {
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName() + " " + i );
        }
    }
}
主类main方法中
        MyThread myThread1 = new MyThread();
        Thread myThread2 = new Thread(myThread1);
        Thread myThread3 = new Thread(myThread1);
        myThread2.start();
        myThread3.start();

方法三

  1. 新建类MyThread实现Callable接口
  2. 实现接口中的call方法(有返回值)
  3. 创建MyThread对象,创建FutureTask对象将MyThread对象当作构造方法参数传入
  4. 创建Thread对象将FutureTask对象当构造方法参数传入(类似方法二第三步)
  5. 通过start方法启动新线程
  6. 通过FutureTask对象get方法获取返回结果

案例:

java 复制代码
class MyThread implements Callable{

    @Override
    public Object call() throws Exception {
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName() + " " + i );
        }
        Thread.sleep(5000);
        return 10+20;
    }
}

main方法中:
        FutureTask futureTask = new FutureTask(new MyThread());
        Thread thread = new Thread(futureTask);
        thread.start();
        Object result = futureTask.get();
        System.out.println("执行结果:"+result);

实际过程中会出现多线程相关问题,比如两个线程同时操控一个实例变量或共享变量,可能会存在数据不一致等问题。


编程模型

同步编程模型:线程一执行必须等待线程二执行结束,或相反,两个线程发生了等待关系。

异步编程模型:线程一和线程二同时执行。

解决方法

方法一

synchronized(锁的内容,通常为全局唯一例如类main.class){

执行的内容

}

方法二

通过Lock lock = new ReentrantLock()对象来上锁

lock.lock();//上锁

执行的内容

lock.unlock();//解锁

守护线程

一般是一个死循环,所有用户结束,守护线程也就结束。

开启方法

复制代码
void setDaemon(true);

方法四

通过wait()和notify(),notifyAll()方法等待和唤醒线程。


线程池

多线程运行时,系统不断创建和销毁新的线程,成本非常高,使用线程池就是最好的选择。

创建

复制代码
ExecutorService threadPoll = Executors.newCachedThreadPool();

threadPoll.execute(对象):线程池指派一个线程执行该对象run方法。

关闭线程池

threadPoll.shutdown();


多把锁

创建

复制代码
CountDownLatch countDownLatch = new CountDownLatch(锁的数量);

锁数量减少

countDownLatch.countDown(); //锁的数量减一

等待

countDownLatch.await():等待子线程执行完再执行(锁的数量为0)


感谢观看------

相关推荐
吃好睡好便好3 小时前
提取矩阵某一行或某一列元素
开发语言·人工智能·线性代数·算法·matlab·矩阵
better_liang6 小时前
每日Java面试场景题知识点之-消息队列MQ核心场景与实战
java·面试·kafka·消息队列·rabbitmq·rocketmq·mq
小江的记录本6 小时前
【JVM虚拟机】垃圾回收GC:四种引用类型:强引用、软引用、弱引用、虚引用(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·后端·python·spring·面试
小马爱打代码6 小时前
Spring源码 第四篇:Spring 5 源码深度拆解:AOP 全流程核心原理
java·后端·spring
deepin_sir6 小时前
10 - 函数
开发语言·python
better_liang6 小时前
每日Java面试场景题知识点之-SpringBoot启动流程
java·面试·springboot·源码解析·启动流程
RyFit7 小时前
Java + AI 实战:Spring AI 从入门到企业级落地
java·人工智能·spring
z落落7 小时前
C#String字符串
开发语言·c#·php
猫头虎-前端技术7 小时前
JS 作用域与闭包:从变量提升到闭包陷阱的超详细解析
开发语言·javascript·云计算·bootstrap·ecmascript·openstack·perl
枫叶林FYL7 小时前
项目十:事件溯源仓储管理系统(WMS)仿真实现
开发语言·python