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)


感谢观看------

相关推荐
尘浮生10 分钟前
Java项目实战II基于微信小程序的南宁周边乡村游平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·微信小程序·小程序·maven
wangjing_05222 小时前
C语言练习.if.else语句.strstr
c语言·开发语言
Tony_long74832 小时前
Python学习——字符串操作方法
开发语言·c#
SoraLuna3 小时前
「Mac玩转仓颉内测版26」基础篇6 - 字符类型详解
开发语言·算法·macos·cangjie
出逃日志3 小时前
JS的DOM操作和事件监听综合练习 (具备三种功能的轮播图案例)
开发语言·前端·javascript
前端青山4 小时前
React事件处理机制详解
开发语言·前端·javascript·react.js
耀耀_很无聊4 小时前
第1章 初识SpringMVC
java·spring·mvc
麻衣带我去上学4 小时前
Spring源码学习(一):Spring初始化入口
java·学习·spring
东阳马生架构4 小时前
MySQL底层概述—1.InnoDB内存结构
java·数据库·mysql
black0moonlight5 小时前
ISAAC Gym 7. 使用箭头进行数据可视化
开发语言·python