java--JUC快速入门(彻底搞懂JUC)

article/2025/10/12 8:46:06

java–JUC快速入门(彻底搞懂JUC)

文章目录

    • java--JUC快速入门(彻底搞懂JUC)
    • 1、学习多线程之前需要知道的一些概念。
    • 2、JUC的结构
    • 3、Lock锁(重点)
    • 4、集合类不安全
    • 5、Callable()
    • 6、常用的辅助类
    • 7、读写锁
    • 8、阻塞队列
    • 9、线程池

1、学习多线程之前需要知道的一些概念。

1.1 JUC是什么?
JUC是java.util.concurrent包的简称,在Java5.0添加,目的就是为了更好的支持高并发任务。让开发者进行多线程编程时减少竞争条件和死锁的问题!
我们在面试过程中也会经常问到这类问题!
1.2 进程与线程的区别

进程 : 一个运行中的程序的集合; 一个进程往往可以包含多个线程,至少包含一个线程

java默认有几个线程? 两个 main线程 gc线程

线程 : 线程(thread)是操作系统能够进行运算调度的最小单位。

1.3 并发与并行的区别:

并发(多线程操作同一个资源,交替执行)
CPU一核, 模拟出来多条线程,天下武功,唯快不破,快速交替
并行(多个人一起行走, 同时进行)
CPU多核,多个线程同时进行 ; 使用线程池操作

1.4 线程有六个状态:

public enum State {// 新生NEW,// 运行RUNNABLE,// 阻塞BLOCKED,// 等待WAITING,//超时等待TIMED_WAITING,//终止TERMINATED;}

1.5 wait/sleep的区别:

  1. 来自不同的类:​ wait来自object类, sleep来自线程类
  2. 关于锁的释放:wait会释放锁, sleep不会释放锁
  3. 使用的范围不同: wait必须在同步代码块中, sleep可以在任何地方睡眠

2、JUC的结构

在这里插入图片描述
1,tools(工具类):又叫信号量三组工具类,包含有

1)CountDownLatch(闭锁) 是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待

2)CyclicBarrier(栅栏) 之所以叫barrier,是因为是一个同步辅助类,允许一组线程互相等待,直到到达某个公共屏障点 ,并且在释放等待线程后可以重用。

3)Semaphore(信号量) 是一个计数信号量,它的本质是一个“共享锁“。信号量维护了一个信号量许可集。线程可以通过调用 acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。

2,executor(执行者):是Java里面线程池的顶级接口,但它只是一个执行线程的工具,真正的线程池接口是ExecutorService,里面包含的类有:

1)ScheduledExecutorService 解决那些需要任务重复执行的问题

2)ScheduledThreadPoolExecutor 周期性任务调度的类实现

3,atomic(原子性包):是JDK提供的一组原子操作类,

包含有AtomicBoolean、AtomicInteger、AtomicIntegerArray等原子变量类,他们的实现原理大多是持有它们各自的对应的类型变量value,而且被volatile关键字修饰了。这样来保证每次一个线程要使用它都会拿到最新的值。

4,locks(锁包):是JDK提供的锁机制,相比synchronized关键字来进行同步锁,功能更加强大,它为锁提供了一个框架,该框架允许更灵活地使用锁包含的实现类有:

1)ReentrantLock 它是独占锁,是指只能被独自占领,即同一个时间点只能被一个线程锁获取到的锁。

2)ReentrantReadWriteLock 它包括子类ReadLock和WriteLock。ReadLock是共享锁,而WriteLock是独占锁。

3)LockSupport 它具备阻塞线程和解除阻塞线程的功能,并且不会引发死锁。

5,collections(集合类):主要是提供线程安全的集合, 比如:

1)ArrayList对应的高并发类是CopyOnWriteArrayList,

2)HashSet对应的高并发类是 CopyOnWriteArraySet,

3)HashMap对应的高并发类是ConcurrentHashMap等等

下面及具体来是学习一下多线程创建及使用方法:

普通的线程代码, 之前都是用的thread或者runnable接口;
具体实现如下:

public class demo01 {public static void main(String[] args) {ThreadDemo threadDemo = new ThreadDemo();threadDemo.start();new Thread(new ThreadDemo2()).start();}
}class ThreadDemo extends Thread{@Overridepublic void run() {System.out.println("普通线程已开启(继承Thread)");}
}
class ThreadDemo2 implements Runnable{@Overridepublic void run() {System.out.println("普通线程已开启(实现Runnable接口)");}
}

程序运行结果:
在这里插入图片描述

3、Lock锁(重点)

传统synchronized
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
  1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
  2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
  3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
  4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

Lock 接口
在这里插入图片描述
实现类
在这里插入图片描述
reentrantLock构造器

  	public ReentrantLock() {sync = new NonfairSync(); //无参默认非公平锁}public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync();//传参为true为公平锁}

公平锁: 十分公平: 可以先来后到,一定要排队
非公平锁: 十分不公平,可以插队(默认)

public class SaleTicketDemo {public static void main(String[] args) {Ticket ticket = new Ticket();new Thread(()->{for(int i = 0; i < 40; i++) ticket.sale();}, "a").start();new Thread(()->{for(int i = 0; i < 40; i++) ticket.sale();}, "b").start();new Thread(()->{for(int i = 0; i < 40; i++) ticket.sale();}, "c").start();}
}class Ticket {private int ticketNum = 30;private Lock lock = new ReentrantLock();public void sale() {lock.lock();try {if (this.ticketNum > 0) {System.out.println(Thread.currentThread().getName() + "购得第" + ticketNum-- + "张票, 剩余" + ticketNum + "张票");}//增加错误的发生几率Thread.sleep(10);} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}}

synchronized和lock锁的区别

  1. synchronized内置的java关键字,Lock是一个java类
  2. synchronized无法判断获取锁的状态, Lock可以判断是否获取到了锁
  3. synchronized会自动释放锁,Lock必须要手动释放锁!如果不是释放锁,会产生死锁
  4. synchronized 线程1(获得锁,阻塞),线程2(等待); Lock锁就不一定会等待下去
  5. synchronized 可重入锁,不可以中断的,非公平的; Lock锁,可重入的,可以判断锁,非公平(可自己设置);
  6. synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码

Condition 精准的通知和唤醒线程
Condition是个接口,基本的方法就是await()和signal()方法;
Condition依赖于Lock接口,生成一个Condition的基本代码是lock.newCondition()
调用Condition的await()和signal()方法,都必须在lock保护之内,就是说必须在lock.lock()和lock.unlock之间才可以使用
Conditon中的await()对应Object的wait();

Condition中的signal()对应Object的notify();

Condition中的signalAll()对应Object的notifyAll()。
在这里插入图片描述

Condition常见例子(生产者消费者模式(完成加一减一各一次操作)):

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class PC {public static void main(String[] args) {a a = new a();new Thread(()->{for (int i =0;i<10;i++){a.increment();}},"A").start();new Thread(()->{for (int i =0;i<10;i++){a.decrease();}},"B").start();}}
class  a{public int nummber=0;Lock lock = new ReentrantLock();Condition condition = lock.newCondition();public   void  increment(){lock.lock();try {while(nummber!=0){condition.await();}nummber++;System.out.println(Thread.currentThread().getName()+">>"+nummber);condition.signalAll();}catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public  void decrease(){lock.lock();try {while(nummber!=1){condition.await();}nummber--;System.out.println(Thread.currentThread().getName()+">>"+nummber);condition.signalAll();}catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}
}

运行结果:
在这里插入图片描述

4、集合类不安全

list 不安全

//java.util.ConcurrentModificationException 并发修改异常!
public class ListTest {public static void main(String[] args) {//并发下 arrayList 是不安全的/*** 解决方案* 1. 使用vector解决* 2. List<String> arrayList = Collections.synchronizedList(new ArrayList<>());* 3. List<String> arrayList = new CopyOnWriteArrayList<>();*///copyOnWrite 写入时复制  COW 计算机程序设计领域的一种优化策略//多个线程调用的时候, list, 读取的时候固定的,写入的时候,可能会覆盖//在写入的时候避免覆盖造成数据问题//CopyOnWriteArrayList 比 vector牛逼在哪里//读写分离List<String> arrayList = new CopyOnWriteArrayList<>();for (int i = 0; i < 100; i++) {new Thread(()->{arrayList.add(UUID.randomUUID().toString().substring(0,5));System.out.println(arrayList);},String.valueOf(i)).start();}}
}

set 不安全

/*** 同理可证*/
public class SetTest {public static void main(String[] args) {//        Set<String> set = new HashSet<>();//如何解决hashSet线程安全问题//1. Set<String> set = Collections.synchronizedSet(new HashSet<>());Set<String> set = new CopyOnWriteArraySet<>();for (int i = 0; i < 100; i++) {new Thread(() -> {set.add(UUID.randomUUID().toString().substring(0, 5));System.out.println(set);}, String.valueOf(i)).start();}}
}

hashSet底层是什么? hashMap

public HashSet() {map = new HashMap<>();
}// add 的本质就是 map 的 key key是无法重复的
public boolean add(E e) {return map.put(e, PRESENT)==null;
}
private static final Object PRESENT = new Object();//这是一个不变的值

HashMap 不安全
map的基本操作

在这里插入图片描述

5、Callable()

在这里插入图片描述

  1. 可以有返回值
  2. 可以抛出异常
  3. 方法不同, run() => call()
    在这里插入图片描述
    在这里插入图片描述
public class CallableTest {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<Integer> futureTask = new FutureTask<>(new MyThread());new Thread(futureTask,"a").start();System.out.println(futureTask.get());}
}class MyThread implements Callable<Integer> {@Overridepublic Integer call() throws Exception {System.out.println("call()方法被调用了");return 1024;}
}

6、常用的辅助类

CountDownLatch
在这里插入图片描述

//计数器
public class demo02 {public static void main(String[] args) throws InterruptedException {//相当于计数器CountDownLatch countDownLatch = new CountDownLatch(5);//计数器总数是5,当减少为0,任务才继续向下执行for (int i = 1; i <6 ; i++) {new Thread(()->{System.out.println(Thread.currentThread().getName()+"==>start");countDownLatch.countDown();}).start();}countDownLatch.await();System.out.println("main线程继续向下执行");}
}

结果:
在这里插入图片描述

原理:

countDownLatch.countDown(); //数量减1

countDownLatch.await();// 等待计数器归零,然后再向下执行

每次有线程调用countDown()数量-1,假设计数器变为0,countDownLatch.await();就会被唤醒,继续执行

cyclicBarrier
在这里插入图片描述
加法计数器

public class CyclicBarrierDemo {public static void main(String[] args) {/*** 集齐77个龙珠召唤神龙*/// 召唤龙珠的线程CyclicBarrier cyclicBarrier = new CyclicBarrier(7, ()->{System.out.println("召唤神龙成功! ");});for (int i = 0; i < 7; i++) {int temp = i;//lambda 能拿到i吗new Thread(()->{System.out.println(Thread.currentThread().getName() + "收集" + temp + "个龙珠");try {cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}).start();}}
}

运行结果:
在这里插入图片描述

Semaphore
在这里插入图片描述

public class SemaphoreTest {public static void main(String[] args) {Semaphore semaphore = new Semaphore(3);for (int i = 0; i < 6; i++) {int temp = i;new Thread(()->{try {semaphore.acquire(); //获取System.out.println(temp + "号车抢到车位");TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();} finally {semaphore.release(); //释放System.out.println(temp + "号车离开车位");}}).start();}}
}

运行结果:
在这里插入图片描述

原理:

semaphore.acquire(); //获取信号量,假设如果已经满了,等待信号量可用时被唤醒

semaphore.release(); //释放信号量

作用: 多个共享资源互斥的使用!并发限流,控制最大的线程数

7、读写锁

ReadWriteLock

在这里插入图片描述

package com.czp.lock;import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;/*** 独占锁(写锁) 一次只能由一个线程占有* 共享锁(读锁) 一次可以有多个线程占有* readWriteLock* 读-读 可以共存* 读-写  不能共存* 写-写 不能共存*/
public class ReadWriteLock {public static void main(String[] args) {MyCacheLock myCache = new MyCacheLock();//写入操作for (int i = 0; i < 6; i++) {int temp = i;new Thread(() -> {myCache.put(temp + "", temp + "");}, String.valueOf(i)).start();}//读取操作for (int i = 0; i < 6; i++) {int temp = i;new Thread(() -> {myCache.get(temp + "");}, String.valueOf(i)).start();}}
}class MyCacheLock {private volatile Map<String, Object> map = new HashMap<>();//读写锁private java.util.concurrent.locks.ReadWriteLock lock = new ReentrantReadWriteLock();// 存,写入的时候只有一个人操作public Object get(String key) {lock.readLock().lock();Object o = null;try {System.out.println(Thread.currentThread().getName() + "读取");try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}o = map.get(key);System.out.println(Thread.currentThread().getName() + "读取ok" + o);} catch (Exception e) {e.printStackTrace();} finally {lock.readLock().unlock();}return o;}public void put(String key, Object value) {lock.writeLock().lock();try {System.out.println(Thread.currentThread().getName() + "写入" + key);map.put(key, value);System.out.println(Thread.currentThread().getName() + "写入完毕");} catch (Exception e) {e.printStackTrace();} finally {lock.writeLock().unlock();}}}class MyCache {private volatile Map<String, Object> map = new HashMap<>();public Object get(String key) {System.out.println(Thread.currentThread().getName() + "读取");Object o = map.get(key);System.out.println(Thread.currentThread().getName() + "读取ok" + o);return o;}public void put(String key, Object value) {System.out.println(Thread.currentThread().getName() + "写入" + key);map.put(key, value);System.out.println(Thread.currentThread().getName() + "写入完毕");}}

8、阻塞队列

在这里插入图片描述
在这里插入图片描述
Blockqueue
在这里插入图片描述
在这里插入图片描述
什么情况下我们会使用阻塞队列,多线程并发处理,线程池!
如何使用队列?
添加 移除
四组API
在这里插入图片描述

/*** 抛出异常*/public static void test1() {//队列的大小ArrayBlockingQueue queue = new ArrayBlockingQueue<>(3);System.out.println(queue.add("a"));System.out.println(queue.add("b"));System.out.println(queue.add("c"));//java.lang.IllegalStateException: Queue full//System.out.println(queue.add("d"));System.out.println("----------------------");System.out.println(queue.remove());System.out.println(queue.remove());System.out.println(queue.remove());//java.util.NoSuchElementExceptionSystem.out.println(queue.remove());//抛出异常}
   /*** 有返回值没有异常*/public static void test2(){ArrayBlockingQueue queue = new ArrayBlockingQueue(3);System.out.println(queue.offer("a"));System.out.println(queue.offer("b"));System.out.println(queue.offer("c"));
//        System.out.println(queue.offer("d"));       //offer 不抛出异常System.out.println(queue.poll());System.out.println(queue.poll());System.out.println(queue.poll());
//        System.out.println(queue.poll());   //null 不抛出异常}
    /*** 等待阻塞*/public static void test3() throws InterruptedException {ArrayBlockingQueue queue = new ArrayBlockingQueue(3);queue.put("a");queue.put("b");queue.put("c");
//        queue.put("c");  队列没有位置就会阻塞System.out.println(queue.take());System.out.println(queue.take());System.out.println(queue.take());}

SynchronizedQueue 同步队列
没有容量,
进去一个元素,必须等待取出来之后,才能再往里面放一个元素
put take


/*** 同步队列* 和其他的lockQueue 不一样, SynchronousQueue 不存储元素*/
public class SyncQueue {public static void main(String[] args) {SynchronousQueue<String> synchronousQueue = new SynchronousQueue<>(); //同步队列new Thread(()->{try {System.out.println(Thread.currentThread().getName() + "put 1");synchronousQueue.put("1");System.out.println(Thread.currentThread().getName() + "put 2");synchronousQueue.put("2");System.out.println(Thread.currentThread().getName() + "put 3");synchronousQueue.put("3");} catch (InterruptedException e) {e.printStackTrace();}},"T1").start();new Thread(()->{try {TimeUnit.SECONDS.sleep(3);System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());TimeUnit.SECONDS.sleep(3);System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());TimeUnit.SECONDS.sleep(3);System.out.println(Thread.currentThread().getName() + "=>" + synchronousQueue.take());} catch (InterruptedException e) {e.printStackTrace();} finally {}},"T2").start();}
}

9、线程池

因为之前有写过这个文章,可以转到以下链接继续学习:

https://blog.csdn.net/weixin_43888181/article/details/116518664?spm=1001.2014.3001.5501

注明:该笔记是通过学习bilibili的狂神说java的视频《JUC并发编程》及个人学习总结所得的笔记。
https://www.bilibili.com/video/BV1B7411L7tE?from=search&seid=15216587814524323096&spm_id_from=333.337.0.0


http://chatgpt.dhexx.cn/article/XJyIBsPQ.shtml

相关文章

Dbeaver做数据迁移

1、选择源头数据库的表、鼠标右击、选择导出数据 2、在数据转化弹框中&#xff0c;双击 ‘数据库&#xff0c;数据表’ 那一栏 3、选择目标数据库&#xff0c;调整字段类型映射关系 4、调整字段的映射关系 目前遇到的字段类型&#xff0c;只有 int&#xff0c;bigint 转 num…

dbeaver工具连接达梦数据库

、一 概述 DBeaver 是一个基于 Java 开发&#xff0c;免费开源的通用数据库管理和开发&#xff0c;DBeaver 采用 Eclipse 框架开发&#xff0c;支持插件扩展&#xff0c;并且提供了许多数据库管理工具&#xff1a;ER 图、数据导入/导出、数据库比较、模拟数据生成等&#xff0…

DBeaver 格式化sql

有时候我们拿到了一条sql语句是长长的&#xff0c;非常不容易阅读&#xff0c;这时我们就想说哪里可以格式下sql代码。 方法有很多种&#xff0c;这里我就用Dbeaver来格式化sql。 ①打开Dbeaver ②复制sql代码到SQL编辑器中&#xff0c;并选中 ③按ctrlshiftF&#xff0c;即…

【DBeaver】常用自定义设置

文章目录 背景一、用户界面设置1.1、22.3.4版本1.1.1、SQL编辑器-字体设置1.1.2、查询结果-字体设置 1.2、23.0.0版本1.2.1、应用字体&#xff08;导航栏等&#xff09;1.2.2、文本字体&#xff08;SQL输出、文本编辑器等&#xff09; 二、常规设置2.1、连接类型设置/环境设置 …

DBeaver导入Excel数据

目录 前言 导入准备 ​导入步骤 1.选中数据库表&#xff0c;右键&#xff0c;然后点击导入数据 2.双击CSV,选择待导入的文件 3.修改编码格式&#xff08;可选&#xff0c;不乱码不用&#xff09; 4.点击下一步&#xff0c;修改列的类型 5.一直下一步&#xff0c;点击…

Dbeaver基本使用

1&#xff1a;与plsql相比&#xff0c;Dbeaver没有右击直接查看表注释的功能&#xff0c;但是Dbeaver提供了一个“打开声明”的功能&#xff0c;里面可以查看一些比较实用的内容&#xff1a;表列注释、创建该表的create语句&#xff1a; 2&#xff1a;在一般开发的情况下&#…

【大数据】Hive可视化工具dbeaver

Hive可视化工具dbeaver 1、dbeaver基本介绍 dbeaver是一个图形化的界面工具&#xff0c;专门用于与各种数据库的集成&#xff0c;通过dbeaver我们可以与各种数据库进行集成通过图形化界面的方式来操作我们的数据库与数据库表&#xff0c;类似于我们的sqlyog或者navicat。 2、…

DBeaver安装及使用手册

一、DBeaver安装 1、在[DBeaver官网](https://dbeaver.io/download)进行数据库工具下载&#xff0c;下载好后双击运行2、选择语言后&#xff0c;点击OK 3、点击下一步 4、接受许可 5、选择可使用者&#xff0c;然后点击下一步 6、选择组件&#xff0c;一般选择默认即可 7…

DBeaver-Driver-All ( DBeaver驱动包,所有JDBC驱动整合包)

DBeaver-Driver-All DBeaver-Driver-All ( DBeaver驱动包 )整合所有DBeaver的JDBC驱动包&#xff0c;供DBeaver使用&#xff0c;无需每次都搜索和下载&#xff0c;只需clone本项目即可&#xff0c;一个包包含几乎所有的驱动&#xff0c;如果有缺漏的驱动欢迎提Issue补充。 DBe…

DBeaver 下载安装

1 下载地址(我下载的 Windows版本&#xff0c;根据系统需要选择版本) Releases dbeaver/dbeaver GitHubFree universal database tool and SQL client. Contribute to dbeaver/dbeaver development by creating an account on GitHub.https://github.com/dbeaver/dbeaver/rel…

DBeaver 安装

DBeaver 目录 DBeaver1、介绍2、发展史3、版本介绍4、下载与安装5、DBeaver 连接数据库&#xff08;MySql&#xff09;6、DBeaver 连接数据库&#xff08;Hive&#xff09;7、DBeaver 功能简介 1、介绍 DBeaver是一种通用数据库管理工具&#xff0c;适用于需要以专业方式使用数…

DBeaver驱动安装

最近打算用DBeaver它来查看SQLite文件&#xff0c;需要安装驱动&#xff0c;总是安装不上有点苦恼 下载驱动的时候可能会出现如下提示&#xff1a; Can’t create driver instance Error creating driver ‘SQLite’ instance. Most likely required jar files are missing. …

使用 DBeaver 导入数据

如何上传数据 在开始使用 DBeaver 之前&#xff0c;用户 以 excel 格式收集了有关电视剧的信息。他的文件已经包含所有必要的列&#xff0c;但我们的英雄不想将其中一些列传输到数据库&#xff0c;因为它们是为他个人使用而创建的&#xff0c;与站点访问者无关。要仅快速加载网…

Dbeaver配置迁移

换电脑了,希望Dbeaver中的连接也一起带过去 但在Dbeaver中找了一圈,没找到可以导出配置的功能 搜了一圈资料并自己尝试,发现配置文件保存在两个文件中,只要把老电脑的这两个文件换到新电脑中就能迁移数据库连接配置

DBeaver 超级详细的安装与使用

一、下载DBeaver DBeaver是一种通用数据库管理工具&#xff0c;适用于需要以专业方式使用数据的每个人&#xff1b;适用于开发人员&#xff0c;数据库管理员&#xff0c;分析师和所有需要使用数据库的人员的免费(DBeaver Community) 的多平台数据库工具。 DBeaver支持80多个数据…

DBeaver安装与使用教程(超详细安装与使用教程)

文章预览&#xff1a; DBeaver安装与使用教程&#xff08;超详细安装与使用教程&#xff09;一、DBeaver安装教程①下载地址②图文安装教程 二、DBeaver使用教程①mysql数据库为例1>填写数据库信息2>常用基本功能 DBeaver安装与使用教程&#xff08;超详细安装与使用教程…

DBeaver下载安装教程

一、简单介绍 DBeaver是一款很好用的数据库连接工具&#xff0c;免费的&#xff0c;支持100多种数据库&#xff08;基本上看得见的数据库不管是关系型还是非关系型的都可用&#xff09; 不过可能需要下载驱动&#xff0c;如果驱动下载不了&#xff0c;连接失败&#xff0c;则…

dbeaver(下载、安装图文过程)

能够帮助你们解决问题是博主的荣幸&#xff0c;你们的支持是我创作的最大动力&#xff01;:)欢迎关注点赞 文章目录 一、dbeaver下载二、dbeaver安装总结 一、dbeaver下载 提示&#xff1a;安装之前需要先确认好自己需要哪个版本的maven&#xff0c;避免浪费时间。 官网下载&am…

DBeaver连接mysql数据库图文教程

文章目录 前言一、DBeaver连接mysql数据库二、文档下载地址 前言 DBeaver是免费、开源、通用数据库工具&#xff0c;是许多开发开发人员和数据库管理员的所选。下面详细介绍Dbeaver连接mysql数据库的过程。 一、DBeaver连接mysql数据库 1、 打开Dbeaver后&#xff0c;按下图…

DBeaver详细使用

DBeaver使用 DBeaver使用相关快捷键数据库表的相关操作界面修改表结构生成相关SQL语句 数据库连接常用类型数据库连接查看已连接数据库相关信息 DBeaver使用 相关快捷键 新增sql编辑页面&#xff1a;ctrl】执行sql语句&#xff1a;CtrlENTERDbeaver提供了“功能模板”&#x…