目录
1.1.3 实现 Callable 接口 + FutureTask
1.2.1.2 使用 ThreadPoolExecutor 创建
1.2.1.2.1 ThreadPoolExecutor 线程池的七大参数
- public class ThreadTest {
- public static void main(String[] args) {
- System.out.println("main...start...");
- // 1. 继承Thread类
- Thread01 thread01 = new Thread01();
- thread01.start(); // 启动线程
- System.out.println("main...end...");
- }
-
- public static class Thread01 extends Thread{
- @Override
- public void run() {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- }
- }
- }
测试结果:
- public class ThreadTest {
-
- public static void main(String[] args) {
- System.out.println("main...start...");
- // 1. 继承Thread类
- //Thread01 thread01 = new Thread01();
- //thread01.start(); // 启动线程
-
- // 2. 实现Runnable接口
- Runnable01 runnable01 = new Runnable01();
- new Thread(runnable01).start();
-
- System.out.println("main...end...");
- }
-
- public static class Thread01 extends Thread{
- @Override
- public void run() {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- }
- }
-
- public static class Runnable01 implements Runnable{
-
- @Override
- public void run() {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- }
- }
- }
FutureTask的get()方法,阻塞式等待整个线程的执行完成,获取线程执行返回结果。
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- // 1. 继承Thread类
- //Thread01 thread01 = new Thread01();
- //thread01.start(); // 启动线程
-
- // 2. 实现Runnable接口
- //Runnable01 runnable01 = new Runnable01();
- //new Thread(runnable01).start();
-
- // 3. 实现Callable接口+FutureTask (可以拿到返回结果,可以处理异常)
- Callable01 callable01 = new Callable01();
- FutureTask
futureTask = new FutureTask<>(callable01); - new Thread(futureTask).start();
- // 阻塞式等待整个线程执行完成,获取线程执行返回结果
- Integer integer = futureTask.get();
-
- System.out.println("main...end..."+integer );
- }
-
- public static class Thread01 extends Thread{
- @Override
- public void run() {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- }
- }
-
- public static class Runnable01 implements Runnable{
-
- @Override
- public void run() {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- }
- }
-
- public static class Callable01 implements Callable
{ -
- @Override
- public Integer call() throws Exception {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- return i;
- }
- }
- }
注意:
Future可以获取异步执行结果;
FutureTask继承了Runnable接口。
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- // 1. 继承Thread类
- //Thread01 thread01 = new Thread01();
- //thread01.start(); // 启动线程
-
- // 2. 实现Runnable接口
- //Runnable01 runnable01 = new Runnable01();
- //new Thread(runnable01).start();
-
- // 3. 实现Callable接口+FutureTask (可以拿到返回结果,可以处理异常)
- //Callable01 callable01 = new Callable01();
- //FutureTask
futureTask = new FutureTask<>(callable01); - //new Thread(futureTask).start();
- 阻塞式等待整个线程执行完成,获取线程执行返回结果
- //Integer integer = futureTask.get();
-
- // 在以后的业务代码里面,以上三种启动线程的方式都不用,因为频繁的创建和销毁线程耗费系统资源。【将所有的多线程异步任务都交给线程池执行】
- //new Thread(()-> System.out.println("hello")).start();
-
- // 4. 线程池 给线程池直接提交业务
-
- // 当前系统中池只有一两个(例如:核心业务/非核心业务),每个异步任务,提交给线程池让它自己去执行就行
- executorService.execute(new Runnable01());
- System.out.println("main...end...");
- }
-
- public static class Thread01 extends Thread{
- @Override
- public void run() {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- }
- }
-
- public static class Runnable01 implements Runnable{
-
- @Override
- public void run() {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- }
- }
-
- public static class Callable01 implements Callable
{ -
- @Override
- public Integer call() throws Exception {
- System.out.println("当前线程:"+Thread.currentThread().getId());
- int i = 10/2;
- System.out.println("运行结果:"+i);
- return i;
- }
- }
- }
- 区别:
- 1、2不能得到返回值;3可以获取返回值
- 1、2、3都不能控制资源
- 4可以控制资源,性能稳定
注意:
1. 在以后的业务代码里面,以上三种启动线程的方式都不用,因为频繁的创建和销毁线程耗费系统资源,可能导致服务器资源耗尽。【将所有的多线程异步任务都交给线程池执行】
2. 当前系统中池只有一两个(例如:核心业务/非核心业务),每个异步任务,提交给线程池让它自己去执行就行
ExecutorService executorService = Executors.newFixedThreadPool(10);
线程池执行任务的两种方式:
executorService.execute(new Runnable01());
Future> submit = executorService.submit(new Runnable01());区别:
execute:参数只能是Runnable,没有返回值。
submit:参数可以是Runnable、Callable,返回值是Future。
- ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
- 200,
- 10,
- TimeUnit.SECONDS,
- new LinkedBlockingQueue<>(100000),
- Executors.defaultThreadFactory(),
- new ThreadPoolExecutor.AbortPolicy());
1、线程池创建,准备好core数量的核心线程,准备接受任务。
2、core 满了, 就将再进来的任务放入阻塞队列中。 空闲的 core 就会自己去阻塞队列获取任务执行。
3、阻塞队列满了, 就直接开新线程执行, 最大只能开到 max 指定的数量
4、如果线程数开到了 max 的数量, 还有新任务进来, 就会使用 RejectedExecutionHandler拒绝任务。
5、max 都执行好了。 Max-core 数量空闲的线程会在 keepAliveTime 指定的时间后自 动销毁。 最终保持到 core 大小 。
问题:一个线程池 core 7; max 20 , queue: 50, 100 并发进来怎么分配的;
答案:先有 7 个能直接得到执行, 接下来 50 个进入队列排队, 在多开 13 个继续执行。 现在 70 个被安排上了。 剩下 30 个默认拒绝策略。
在 Java 8 中, 新增加了一个包含 50 个方法左右的类: CompletableFuture, 提供了非常强大的Future 的扩展功能, 可以帮助我们简化异步编程的复杂性, 提供了函数式编程的能力, 可以通过回调的方式处理计算结果, 并且提供了转换和组合 CompletableFuture 的方法。CompletableFuture 类实现了 Future 接口, 所以你还是可以像以前一样通过`get`方法阻塞或者轮询的方式获得结果, 但是这种方式不推荐使用。
CompletableFuture 和 FutureTask 同属于 Future 接口的实现类, 都可以获取线程的执行结果。
CompletableFuture 提供了四个静态方法来创建一个异步操作。
- public static CompletableFuture
runAsync(Runnable runnable) - public static CompletableFuture
runAsync(Runnable runnable,Executor executor) - public static CompletableFuture supplyAsync(Supplier supplier)
- public static CompletableFuture supplyAsync(Supplier supplier,Executor executor)
注意:
(1)runAsync都是没有返回结果的,supplyAsync都是可以获取返回结果的;
(2)可以传入自定义的线程池,否则就用默认的线程池;
(3)Async代表异步方法。
- public static void main(String[] args) {
- System.out.println("main...start...");
- CompletableFuture
future = CompletableFuture.runAsync(() -> { - System.out.println("当前线程:" + Thread.currentThread().getId());
- int i = 10 / 2;
- System.out.println("运行结果:" + i);
- }, executorService);
-
- System.out.println("main...end...");
- }
测试结果:
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture
future = CompletableFuture.supplyAsync(() -> { - System.out.println("当前线程:" + Thread.currentThread().getId());
- int i = 10 / 2;
- System.out.println("运行结果:" + i);
- return i;
- }, executorService);
- Integer integer = future.get();
- System.out.println("main...end..."+integer);
- }
测试结果:
- public CompletableFuture
whenComplete(BiConsumer super T, ? super Throwable> action) - public CompletableFuture
whenCompleteAsync(BiConsumer super T, ? super Throwable> action) - public CompletableFuture
whenCompleteAsync(BiConsumer super T, ? super Throwable> action, Executor executor) -
- public CompletableFuture
exceptionally(Function fn)
whenComplete可以处理正常和异常的结果, exceptionally 处理异常情况。
whenComplete 和 whenCompleteAsync 的区别:
注意:方法不以 Async 结尾, 意味着 Action 使用相同的线程执行, 而 Async 可能会使用其他线程执行(如果是使用相同的线程池, 也可能会被同一个线程选中执行)
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- //CompletableFuture
future = CompletableFuture.runAsync(() -> { - // System.out.println("当前线程:" + Thread.currentThread().getId());
- // int i = 10 / 2;
- // System.out.println("运行结果:" + i);
- //}, executorService);
- CompletableFuture
future = CompletableFuture.supplyAsync(() -> { - System.out.println("当前线程:" + Thread.currentThread().getId());
- int i = 10 / 1;
- System.out.println("运行结果:" + i);
- return i;
- }, executorService).whenComplete((result,exception)->{
- // 可以感知到异常,但无法修改返回数据
- System.out.println("异步任务完成了...返回值为:"+result+";异常为:"+exception);
- });
- //Integer integer = future.get();
- System.out.println("main...end...");
- }
- }
将 int i = 10/1; 改为 int i = 10/0;
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- //CompletableFuture
future = CompletableFuture.runAsync(() -> { - // System.out.println("当前线程:" + Thread.currentThread().getId());
- // int i = 10 / 2;
- // System.out.println("运行结果:" + i);
- //}, executorService);
- CompletableFuture
future = CompletableFuture.supplyAsync(() -> { - System.out.println("当前线程:" + Thread.currentThread().getId());
- int i = 10 / 2;
- System.out.println("运行结果:" + i);
- return i;
- }, executorService).whenComplete((result,exception)->{
- // 可以感知到异常,但无法修改返回数据
- System.out.println("异步任务完成了...返回值为:"+result+";异常为:"+exception);
- }).exceptionally(throwable -> {
- // 可以感知异常,同时返回默认值
- return 10;
- });
- Integer integer = future.get();
- System.out.println("main...end..."+integer);
- }
- }
将 int i = 10/2; 改为 int i = 10/0;
一般用handle,因为whencomplete如果异常不能给定默认返回结果,需要再调用exceptionally,而handle可以。
handle方法作用:获得前一任务的返回值【handleAsync可以是异步执行的】,也可以处理上一任务的异常,调用exceptionally修改前一任务的返回值【只有在异常情况时给一个默认返回值】而handle方法可以简化操作。
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- //CompletableFuture
future = CompletableFuture.runAsync(() -> { - // System.out.println("当前线程:" + Thread.currentThread().getId());
- // int i = 10 / 2;
- // System.out.println("运行结果:" + i);
- //}, executorService);
- /**
- * 方法执行完成后的感知
- */
- //CompletableFuture
future = CompletableFuture.supplyAsync(() -> { - // System.out.println("当前线程:" + Thread.currentThread().getId());
- // int i = 10 / 2;
- // System.out.println("运行结果:" + i);
- // return i;
- //}, executorService).whenComplete((result,exception)->{
- // // 可以感知到异常,但无法修改返回数据
- // System.out.println("异步任务完成了...返回值为:"+result+";异常为:"+exception);
- //}).exceptionally(throwable -> {
- // // 可以感知异常,同时返回默认值
- // return 10;
- //});
- /**
- * 方法执行完成后的处理
- */
- CompletableFuture
future = CompletableFuture.supplyAsync(() -> { - System.out.println("当前线程:" + Thread.currentThread().getId());
- int i = 10 / 4;
- System.out.println("运行结果:" + i);
- return i;
- }).handle((res, thr) -> {
- if (res != null) {
- return res * 2;
- }
- if (thr != null) {
- return 10;
- }
- return 0;
- });
- // R apply(T t, U u);
- Integer integer = future.get();
- System.out.println("main...end..."+integer);
- }
- }
将 int i = 10/4; 改为 int i = 10/0;
- public CompletableFuture thenApply(Function super T,? extends U> fn)
- public CompletableFuture thenApplyAsync(Function super T,? extends U> fn)
- public CompletableFuture thenApplyAsync(Function super T,? extends U> fn, Executor executor)
-
- public CompletableFuture
thenAccept(Consumer super T> action) - public CompletableFuture
thenAcceptAsync(Consumer super T> action) - public CompletableFuture
thenAcceptAsync(Consumer super T> action,Executor executor) -
- public CompletableFuture
thenRun(Runnable action) - public CompletableFuture
thenRunAsync(Runnable action) - public CompletableFuture
thenRunAsync(Runnable action,Executor executor)
thenApply 方法: 当一个线程依赖另一个线程时, 获取上一个任务返回的结果, 并返回当前
任务的返回值。
thenAccept 方法: 消费处理结果。 接收任务的处理结果, 并消费处理, 无返回结果。
thenRun 方法: 只要上面的任务执行完成, 就开始执行 thenRun, 只是处理完任务后, 执行
thenRun 的后续操作
带有 Async 默认是异步执行的。 同之前。
以上都要前置任务成功完成。
Function super T,? extends U>
T: 上一个任务返回结果的类型。
U: 当前任务的返回值类型 。
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture.supplyAsync(() -> {
- System.out.println("当前线程:" + Thread.currentThread().getId());
- int i = 10 / 4;
- System.out.println("运行结果:" + i);
- return i;
- }).thenRunAsync(()->{
- // 不接收上一步结果,无返回值
- System.out.println("任务2启动了...");
- },executorService);
- System.out.println("main...end...");
- }
执行结果:
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture.supplyAsync(() -> {
- System.out.println("当前线程:" + Thread.currentThread().getId());
- int i = 10 / 4;
- System.out.println("运行结果:" + i);
- return i;
- }).thenAcceptAsync(res -> {
- // thenRunAsync:不接收上一步结果,无返回值
- // thenAcceptAsync:接收上一步结果,无返回值 void accept(T t);
- System.out.println("任务2启动了..." + res);
- }, executorService);
- System.out.println("main...end...");
- }
执行结果:
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture
future = CompletableFuture.supplyAsync(() -> { - System.out.println("当前线程:" + Thread.currentThread().getId());
- int i = 10 / 4;
- System.out.println("运行结果:" + i);
- return i;
- }).thenApplyAsync(res -> {
- // thenRunAsync:不接收上一步结果,无返回值
- // thenAcceptAsync:接收上一步结果,无返回值 void accept(T t);
- // thenApplyAsync:接收上一步结果,有返回值 R apply(T t);
- System.out.println("任务2启动了..." + res);
- return "Hello" + res;
- }, executorService);
- System.out.println("main...end..."+future.get());
- }
执行结果:
- public CompletableFuture
thenCombine(CompletionStage extends U> other, - BiFunction super T,? super U,? extends V> fn)
- public CompletableFuture
thenCombineAsync(CompletionStage extends U> other, - BiFunction super T,? super U,? extends V> fn)
- public CompletableFuture
thenCombineAsync(CompletionStage extends U> other, - BiFunction super T,? super U,? extends V> fn, Executor executor)
-
- public CompletableFuture
thenAcceptBoth(CompletionStage extends U> other, - BiConsumer super T, ? super U> action)
- public CompletableFuture
thenAcceptBothAsync(CompletionStage extends U> other, - BiConsumer super T, ? super U> action)
- public CompletableFuture
thenAcceptBothAsync(CompletionStage extends U> other, - BiConsumer super T, ? super U> action, Executor executor)
-
- public CompletableFuture
runAfterBoth(CompletionStage> other,Runnable action) - public CompletableFuture
runAfterBothAsync(CompletionStage> other,Runnable action) - public CompletableFuture
runAfterBothAsync(CompletionStage> other,Runnable action, - Executor executor)
两个任务必须都完成, 触发该任务。
thenCombine: 组合两个 future, 获取两个 future 的返回结果, 并返回当前任务的返回值
thenAcceptBoth: 组合两个 future, 获取两个 future 任务的返回结果, 然后处理任务, 没有
返回值。
runAfterBoth: 组合两个 future, 不需要获取 future 的结果, 只需两个 future 处理完任务后,
处理该任务。
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- /**
- * 两个任务组合-都要完成
- */
- CompletableFuture
future01 = CompletableFuture.supplyAsync(() -> { - System.out.println("任务1线程:"+Thread.currentThread().getId());
- int i = 10/4;
- System.out.println("任务1结束。。。");
- return i;
- }, executorService);
- CompletableFuture
future02 = CompletableFuture.supplyAsync(() -> { - System.out.println("任务2线程:"+Thread.currentThread().getId());
- System.out.println("任务2结束。。。");
- return "Hello";
- }, executorService);
- future01.runAfterBothAsync(future02,()->{
- System.out.println("任务3开始");
- },executorService);
- System.out.println("main...end...");
- }
- }
执行结果:
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- /**
- * 两个任务组合-都要完成
- */
- CompletableFuture
future01 = CompletableFuture.supplyAsync(() -> { - System.out.println("任务1线程:"+Thread.currentThread().getId());
- int i = 10/4;
- System.out.println("任务1结束。。。");
- return i;
- }, executorService);
- CompletableFuture
future02 = CompletableFuture.supplyAsync(() -> { - System.out.println("任务2线程:"+Thread.currentThread().getId());
- System.out.println("任务2结束。。。");
- return "Hello";
- }, executorService);
- //future01.runAfterBothAsync(future02,()->{
- // System.out.println("任务3开始");
- //},executorService);
- future01.thenAcceptBothAsync(future02,(f1,f2)->{
- //void accept(T t, U u);
- System.out.println("任务3开始。。。之前的结果:"+f1+"->"+f2);
- },executorService);
- System.out.println("main...end...");
- }
- }
执行结果:
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- /**
- * 两个任务组合-都要完成
- */
- CompletableFuture
future01 = CompletableFuture.supplyAsync(() -> { - System.out.println("任务1线程:"+Thread.currentThread().getId());
- int i = 10/4;
- System.out.println("任务1结束。。。");
- return i;
- }, executorService);
- CompletableFuture
future02 = CompletableFuture.supplyAsync(() -> { - System.out.println("任务2线程:"+Thread.currentThread().getId());
- System.out.println("任务2结束。。。");
- return "Hello";
- }, executorService);
- //future01.runAfterBothAsync(future02,()->{
- // System.out.println("任务3开始");
- //},executorService);
- //future01.thenAcceptBothAsync(future02,(f1,f2)->{
- // //void accept(T t, U u);
- // System.out.println("任务3开始。。。之前的结果:"+f1+"->"+f2);
- //},executorService);
- CompletableFuture
future = future01.thenCombineAsync(future02, (f1, f2) -> { - return f1 + "->" + f2 + "->相柳"; // R apply(T t, U u);
- }, executorService);
- System.out.println("main...end..."+future.get());
- }
- }
执行结果:
- public CompletableFuture applyToEither(CompletionStage extends T> other, Function super T, U> fn)
- public CompletableFuture applyToEitherAsync(CompletionStage extends T> other, Function super T, U> fn)
- public CompletableFuture applyToEitherAsync(CompletionStage extends T> other, Function super T, U> fn,Executor executor)
-
- public CompletableFuture
acceptEither(CompletionStage extends T> other, Consumer super T> action) - public CompletableFuture
acceptEitherAsync(CompletionStage extends T> other, Consumer super T> action) - public CompletableFuture
acceptEitherAsync(CompletionStage extends T> other, Consumer super T> action,Executor executor) -
- public CompletableFuture
runAfterEither(CompletionStage> other,Runnable action) - public CompletableFuture
runAfterEitherAsync(CompletionStage> other,Runnable action) - public CompletableFuture
runAfterEitherAsync(CompletionStage> other,Runnable action,Executor executor)
当两个任务中, 任意一个 future 任务完成的时候, 执行任务。
applyToEither: 两个任务有一个执行完成, 获取它的返回值, 处理任务并有新的返回值。
acceptEither: 两个任务有一个执行完成, 获取它的返回值, 处理任务, 没有新的返回值。
runAfterEither: 两个任务有一个执行完成, 不需要获取 future 的结果, 处理任务, 也没有返
回值。
线程1执行完成,线程2睡了3秒,达成runAfterEitherAsync执行条件
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture
future01 = CompletableFuture.supplyAsync(() -> { - System.out.println("任务1线程:"+Thread.currentThread().getId());
- int i = 10/4;
- System.out.println("任务1结束。。。");
- return i;
- }, executorService);
- CompletableFuture
future02 = CompletableFuture.supplyAsync(() -> { - System.out.println("任务2线程:"+Thread.currentThread().getId());
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("任务2结束。。。");
- return "Hello";
- }, executorService);
-
- /**
- * 两个任务,只要有一个完成,我们就执行任务3
- */
- future01.runAfterEitherAsync(future02,()->{
- System.out.println("任务3开始。。。之前的结果:");
- },executorService);
- System.out.println("main...end...");
- }
- }
执行结果:
两个任务的返回值类型要一致,这里全改为Object
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture
- System.out.println("任务1线程:"+Thread.currentThread().getId());
- int i = 10/4;
- System.out.println("任务1结束。。。");
- return i;
- }, executorService);
- CompletableFuture
- System.out.println("任务2线程:"+Thread.currentThread().getId());
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("任务2结束。。。");
- return "Hello";
- }, executorService);
- /**
- * 两个任务,只要有一个完成,我们就执行任务3
- */
- //future01.runAfterEitherAsync(future02,()->{
- // System.out.println("任务3开始。。。之前的结果:");
- //},executorService);
- future01.acceptEitherAsync(future02,res->{
- System.out.println("任务3开始。。。之前的结果:"+res);
- },executorService);
- System.out.println("main...end...");
- }
- }
执行结果:
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture
- System.out.println("任务1线程:"+Thread.currentThread().getId());
- int i = 10/4;
- System.out.println("任务1结束。。。");
- return i;
- }, executorService);
- CompletableFuture
- System.out.println("任务2线程:"+Thread.currentThread().getId());
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("任务2结束。。。");
- return "Hello";
- }, executorService);
- /**
- * 两个任务,只要有一个完成,我们就执行任务3
- */
- //future01.runAfterEitherAsync(future02,()->{
- // System.out.println("任务3开始。。。之前的结果:");
- //},executorService);
- //future01.acceptEitherAsync(future02,res->{
- // System.out.println("任务3开始。。。之前的结果:"+res);
- //},executorService);
- CompletableFuture
future = future01.applyToEitherAsync(future02, res -> { - System.out.println("任务3开始。。。之前的结果:"+res);
- return res.toString() + "九头蛇";
- }, executorService);
- System.out.println("main...end..."+future.get());
- }
- }
执行结果:
- public static CompletableFuture
allOf(CompletableFuture>... cfs) -
- public static CompletableFuture
allOf: 等待所有任务完成
anyOf: 只要有一个任务完成
让查询商品介绍睡3秒钟,便于观察。
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture
futureImg = CompletableFuture.supplyAsync(() -> { - System.out.println("查询商品的图片信息");
- return "hello.jpg";
- }, executorService);
- CompletableFuture
futureAttr = CompletableFuture.supplyAsync(() -> { - System.out.println("查询商品的属性");
- return "白色+256G";
- }, executorService);
- CompletableFuture
futureDesc = CompletableFuture.supplyAsync(() -> { - try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("查询商品介绍");
- return "小米";
- }, executorService);
-
- CompletableFuture
allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc); - allOf.get();// 等待所有任务完成
-
- System.out.println("main...end..."+futureImg.get()+"->"+futureAttr.get()+">"+futureDesc.get());
- }
- }
执行结果:
- public class ThreadTest {
- public static ExecutorService executorService = Executors.newFixedThreadPool(10);
-
-
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- System.out.println("main...start...");
- CompletableFuture
futureImg = CompletableFuture.supplyAsync(() -> { - System.out.println("查询商品的图片信息");
- return "hello.jpg";
- }, executorService);
- CompletableFuture
futureAttr = CompletableFuture.supplyAsync(() -> { - System.out.println("查询商品的属性");
- return "白色+256G";
- }, executorService);
- CompletableFuture
futureDesc = CompletableFuture.supplyAsync(() -> { - try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("查询商品介绍");
- return "小米";
- }, executorService);
-
- //CompletableFuture
allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc); - //allOf.get();// 等待所有任务完成
- //System.out.println("main...end..."+futureImg.get()+"->"+futureAttr.get()+">"+futureDesc.get());
- CompletableFuture
- System.out.println("main...end..."+anyOf.get());
- }
- }
执行结果:
添加商品详情的域名与ip映射:172.1.11.10 item.gulimall.com
配置域名 item.gulimall.com,这里之前应该配置过,如下:
server_name gulimall.com *.gulimall.com;
- # 打开nginx配置文件
- vi /root/docker/nginx/conf/conf.d/gulimall.conf
将商品详情域名(item.gulimall.com)访问转发的商品服务。
- - id: gulimall_host_route
- uri: lb://gulimall-product
- predicates:
- # 由以下的主机域名访问转发到商品服务
- - Host=gulimall.com,item.gulimall.com
- 1. 将shangpinxiangqing.html复制到gulimall-product/src/main/resources/templates,并改名为item.html;
- 2. 将静态资源放到nginx的/root/docker/nginx/html/static/item/路径下;
- 3. 将item.html页面的href和src以/static/item/开头。
- 4. 在gulimall-product/src/main/java/com/wen/gulimall/product/web/下编写ItemController.java;
- 5. 启动网关服务、商品服务、搜索服务,进行测试:
- 1)在搜索服务点击某个商品发现无法跳转至商品详情服务,修改搜索服务list.html,如下:
- 通过右键商品审查元素,发现需要修改class="da"的图片跳转路径,如下:
"da">
- "${product.skuImg}" class="dim">
-
- @Controller
- public class ItemController {
-
- @GetMapping("/{skuId}.html")
- public String item(@PathVariable Long skuId){
- System.out.println("准备查询:"+skuId+"的详情!");
- return "item";
- }
- }
封装页面需要的详情数据模型,如下:
- @Data
- public class SkuItemVo {
- // 获取sku的基本信息 pms_sku_info
- private SkuInfoEntity info;
-
- // 获取sku的图片信息 pms_sku_images
- private List
images; -
- // 获取spu的销售属性组合
- private List
saleAttr; -
- // 获取spu的介绍
- private SpuInfoDescEntity desc;
-
- // 获取spu的规格参数信息
- private List
groupAttrs; -
- }
- @ToString
- @Data
- public class SpuItemAttrGroupVo {
- private String groupName;
- private List
attrs; - }
- // 之前代码中存在
- @Data
- public class Attr {
- private Long attrId;
- private String attrName;
- private String attrValue;
- }
- @ToString
- @Data
- public class SkuItemSaleAttrVo {
- private Long attrId;
- private String attrName;
- private List
attrValues; - }
- @Data
- public class AttrValueAndWithSkuIdVo {
- // 属性值
- private String attrValue;
- // 属性编号,属性名,属性值对应的所有skuId
- private String skuIds;
- }
- @Controller
- public class ItemController {
- @Resource
- private SkuInfoService skuInfoService;
-
- @GetMapping("/{skuId}.html")
- public String item(@PathVariable Long skuId, Model model){
- // 获取sku的基本信息 pms_sku_info
- // 获取sku的图片信息 pms_sku_images
- // 获取spu的销售属性组合
- // 获取spu的介绍
- // 获取spu的规格参数信息
- SkuItemVo vo = skuInfoService.item(skuId);
- model.addAttribute("item",vo);
- return "item";
- }
- }
- public interface SkuInfoService extends IService
{ -
- ...
-
- SkuItemVo item(Long skuId);
- }
- @Service("skuInfoService")
- public class SkuInfoServiceImpl extends ServiceImpl
implements SkuInfoService { -
- @Resource
- private SkuImagesService skuImagesService;
- @Resource
- private SpuInfoDescService spuInfoDescService;
- @Resource
- private AttrGroupService attrGroupService;
- @Resource
- private SkuSaleAttrValueService skuSaleAttrValueService;
-
- ...
-
-
- @Override
- public SkuItemVo item(Long skuId) {
- SkuItemVo skuItemVo = new SkuItemVo();
- // 获取sku的基本信息 pms_sku_info
- SkuInfoEntity info = getById(skuId);
- skuItemVo.setInfo(info);
- Long spuId = info.getSpuId();
- Long catalogId = info.getCatalogId();
-
- // 获取sku的图片信息 pms_sku_images
- List
images = skuImagesService.getImagesBySkuId(skuId); - skuItemVo.setImages(images);
- // 获取spu的销售属性组合
- List
saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(spuId); - skuItemVo.setSaleAttr(saleAttrVos);
- // 获取spu的介绍
- SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(spuId);
- skuItemVo.setDesc(spuInfoDescEntity);
-
- // 获取spu的规格参数信息
- List
attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(spuId,catalogId); - skuItemVo.setGroupAttrs(attrGroupVos);
- return skuItemVo;
- }
-
- }
- public interface SkuImagesService extends IService
{ -
- ...
-
- List
getImagesBySkuId(Long skuId); - }
- @Service("skuImagesService")
- public class SkuImagesServiceImpl extends ServiceImpl
implements SkuImagesService { -
- ...
-
- @Override
- public List
getImagesBySkuId(Long skuId) { - List
imagesEntities = this.baseMapper.selectList(new QueryWrapper().eq("sku_id", skuId)); - return imagesEntities;
- }
-
- }
- public interface AttrGroupService extends IService
{ -
- ...
-
- List
getAttrGroupWithAttrsBySpuId(Long spuId, Long catalogId); - }
- @Service("attrGroupService")
- public class AttrGroupServiceImpl extends ServiceImpl
implements AttrGroupService { -
- ...
-
- @Override
- public List
getAttrGroupWithAttrsBySpuId(Long spuId, Long catalogId) { - List
vos = this.baseMapper.getAttrGroupWithAttrsBySpuId(spuId,catalogId); - return vos;
- }
- }
- @Mapper
- public interface AttrGroupDao extends BaseMapper
{ -
- List
getAttrGroupWithAttrsBySpuId(@Param("spuId") Long spuId, @Param("catalogId") Long catalogId); -
- }
- "1.0" encoding="UTF-8"?>
- mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
- <mapper namespace="com.wen.gulimall.product.dao.AttrGroupDao">
-
- <resultMap id="spuItemAttrGroupVo" type="com.wen.gulimall.product.vo.SpuItemAttrGroupVo">
- <result property="groupName" column="groupName"/>
- <collection property="attrs" ofType="com.wen.gulimall.product.vo.Attr">
- <result property="attrName" column="attrName"/>
- <result property="attrValue" column="attrValue"/>
- collection>
- resultMap>
- <select id="getAttrGroupWithAttrsBySpuId" resultMap="spuItemAttrGroupVo">
- SELECT
- pav.spu_id,
- ag.attr_group_id,
- ag.attr_group_name groupName,
- attr.attr_name attrName,
- pav.attr_value attrValue
- FROM pms_attr_group ag LEFT JOIN pms_attr_attrgroup_relation aar ON (ag.attr_group_id=aar.attr_group_id)
- LEFT JOIN pms_attr attr ON (aar.attr_id=attr.attr_id)
- LEFT JOIN pms_product_attr_value pav ON (attr.attr_id = pav.attr_id)
- WHERE ag.catelog_id = #{catalogId} AND pav.spu_id = #{spuId}
- select>
-
- mapper>
- public interface SkuSaleAttrValueService extends IService
{ -
- ...
-
- List
getSaleAttrsBySpuId(Long spuId); - }
- @Service("skuSaleAttrValueService")
- public class SkuSaleAttrValueServiceImpl extends ServiceImpl
implements SkuSaleAttrValueService { -
- ...
-
- @Override
- public List
getSaleAttrsBySpuId(Long spuId) { - List
vos = this.baseMapper.getSaleAttrsBySpuId(spuId); - return vos;
- }
-
- }
- @Mapper
- public interface SkuSaleAttrValueDao extends BaseMapper
{ -
- List
getSaleAttrsBySpuId(@Param("spuId") Long spuId); - }
- "1.0" encoding="UTF-8"?>
- mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
- <mapper namespace="com.wen.gulimall.product.dao.SkuSaleAttrValueDao">
-
- <resultMap id="skuItemSaleAttrVo" type="com.wen.gulimall.product.vo.SkuItemSaleAttrVo">
- <result property="attrId" column="attr_id"/>
- <result property="attrName" column="attr_name"/>
- <collection property="attrValues" ofType="com.wen.gulimall.product.vo.AttrValueAndWithSkuIdVo">
- <result property="attrValue" column="attr_value"/>
- <result property="skuIds" column="sku_ids"/>
- collection>
- resultMap>
- <select id="getSaleAttrsBySpuId" resultMap="skuItemSaleAttrVo">
- SELECT
- ssav.attr_id,
- ssav.attr_name,
- ssav.attr_value,
- GROUP_CONCAT(DISTINCT info.sku_id) sku_ids
- FROM pms_sku_info info LEFT JOIN pms_sku_sale_attr_value ssav ON info.sku_id=ssav.sku_id
- WHERE info.spu_id=#{spuId}
- GROUP BY ssav.attr_id,ssav.attr_name,ssav.attr_value
- select>
- mapper>
- html>
- <html xmlns:th="http://www.thymeleaf.org">
-
- <head>
- <meta charset="UTF-8">
- <title>title>
- <link rel="stylesheet" type="text/css" href="/static/item/scss/shop.css" />
- <link rel="stylesheet" type="text/css" href="/static/item/scss/jd.css"/>
- <link rel="stylesheet" href="/static/item/scss/header.css" />
- <link rel="stylesheet" type="text/css" href="/static/item/bootstrap/css/bootstrap.css"/>
- head>
- <body>
- <div id="max">
- <header>
-
- <div class="min">
- <ul class="header_ul_left">
- <li class="glyphicon glyphicon-home"> <a href="/static/item/shouye.html" class="aa">京东首页a>li>
- <li class="glyphicon glyphicon-map-marker"> <a href="/static/item/javascript:;">北京a>
- <ol id="beijing">
- <li style="background: red;"><a href="javascript:;" style="color: white;">北京a>li>
- <li><a href="javascript:;">上海a>li>
- <li><a href="javascript:;">天津a>li>
- <li><a href="javascript:;">重庆a>li>
- <li><a href="javascript:;">河北a>li>
- <li><a href="javascript:;">山西a>li>
- <li><a href="javascript:;">河南a>li>
- <li><a href="javascript:;">辽宁a>li>
- <li><a href="javascript:;">吉林a>li>
- <li><a href="javascript:;">黑龙江a>li>
- <li><a href="javascript:;">内蒙古a>li>
- <li><a href="javascript:;">江苏a>li>
- <li><a href="javascript:;">山东a>li>
- <li><a href="javascript:;">安徽a>li>
- <li><a href="javascript:;">浙江a>li>
- <li><a href="javascript:;">福建a>li>
- <li><a href="javascript:;">湖北a>li>
- <li><a href="javascript:;">湖南a>li>
- <li><a href="javascript:;">广东a>li>
- <li><a href="javascript:;">广西a>li>
- <li><a href="javascript:;">江西a>li>
- <li><a href="javascript:;">四川a>li>
- <li><a href="javascript:;">海南a>li>
- <li><a href="javascript:;">贵州a>li>
- <li><a href="javascript:;">云南a>li>
- <li><a href="javascript:;">西藏a>li>
- <li><a href="javascript:;">陕西a>li>
- <li><a href="javascript:;">甘肃a>li>
- <li><a href="javascript:;">青海a>li>
- <li><a href="javascript:;">宁夏a>li>
- <li><a href="javascript:;">新疆a>li>
- <li><a href="javascript:;">港澳a>li>
- <li><a href="javascript:;">台湾a>li>
- <li><a href="javascript:;">钓鱼岛a>li>
- <li><a href="javascript:;">海外a>li>
- ol>
- li>
- ul>
- <ul class="header_ul_right">
- <li style="border: 0;"><a href="../登录页面\index.html" class="aa">你好,请登录a>li>
- <li><a href="../注册页面\index.html" style="color: red;">免费注册a> |li>
- <li><a href="javascript:;" class="aa">我的订单a> |li>
- <li class="jingdong"><a href="javascript:;">我的京东a><span class="glyphicon glyphicon-menu-down">|span>
- <ol class="jingdong_ol">
- <li><a href="javascript:;">待处理订单a>li>
- <li><a href="javascript:;">消息a>li>
- <li><a href="javascript:;">返修退换货a>li>
- <li><a href="javascript:;">我的回答a>li>
- <li><a href="javascript:;">降价商品a>li>
- <li><a href="javascript:;">我的关注a>li>
- <li style="width: 100%;height: 1px;background: lavender;margin-top: 15px;">li>
- <li style="margin-top: 0;"><a href="javascript:;">我的京豆a>li>
- <li style="margin-top: 0;"><a href="javascript:;">我的优惠券a>li>
- <li style="margin-bottom: 10px;"><a href="javascript:;">我的白条a>li>
-
- ol>
- li>
-
- <li><a href="javascript:;" class="aa">京东会员a> |li>
- <li><a href="javascript:;" class="aa">企业采购a> |li>
- <li class="fuwu"><a href="javascript:;">客户服务a><span class="glyphicon glyphicon-menu-down">span> |
- <ol class="fuwu_ol">
- <h6>客户h6>
- <li><a href="javascript:;">帮助中心a>li>
- <li><a href="javascript:;">售后服务a>li>
- <li><a href="javascript:;">在线客服a>li>
- <li><a href="javascript:;">意见建议a>li>
- <li><a href="javascript:;">电话客服a>li>
- <li><a href="javascript:;">客服邮箱a>li>
- <li style="margin-bottom: -5px;"><a href="javascript:;">金融咨询a>li>
- <li style="margin-bottom: -5px;"><a href="javascript:;">售全球客服a>li>
- <h6 style="border-top: 1px dashed darkgray;height: 30px;line-height: 30px;">商户h6>
- <li style="margin-top: -5px;"><a href="javascript:;">合作招商a>li>
- <li style="margin-top: -5px;"><a href="javascript:;">学习中心a>li>
- <li><a href="javascript:;">商家后台a>li>
- <li><a href="javascript:;">京麦工作台a>li>
- <li><a href="javascript:;">商家帮助a>li>
- <li><a href="javascript:;">规则平台a>li>
- ol>
- li>
- <li class="daohang"><a href="javascript:;">网站导航a><span class="glyphicon glyphicon-menu-down">span> |
- <ol class="daohang_ol">
- <li style="width: 34%;">
- <h5>特色主题h5>
- <p>
- <a href="javascript:;">京东试用a>
- <a href="javascript:;">京东金融a>
- <a href="javascript:;">全球售a>
- <a href="javascript:;">国际站a>
- p>
- <p>
- <a href="javascript:;">京东会员a>
- <a href="javascript:;">京东预售a>
- <a href="javascript:;">买什么a>
- <a href="javascript:;">俄语站a>
- p>
- <p>
- <a href="javascript:;">装机大师a>
- <a href="javascript:;">0元评测a>
- <a href="javascript:;">定期送a>
- <a href="javascript:;">港澳售a>
- p>
- <p>
- <a href="javascript:;">优惠券a>
- <a href="javascript:;">秒杀a>
- <a href="javascript:;">闪购a>
- <a href="javascript:;">印尼站a>
- p>
- <p>
- <a href="javascript:;">京东金融科技a>
- <a href="javascript:;">In货推荐a>
- <a href="javascript:;">陪伴计划a>
- <a href="javascript:;">出海招商a>
- p>
- li>
- <li>
- <h5>行业频道h5>
- <p>
- <a href="javascript:;" class="aa_2">手机a>
- <a href="javascript:;" class="aa_2">智能数码a>
- <a href="javascript:;" class="aa_2">玩3Ca>
- p>
- <p>
- <a href="javascript:;" class="aa_2">电脑办公a>
- <a href="javascript:;" class="aa_2">家用电器a>
- <a href="javascript:;" class="aa_2">京东智能a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">服装城a>
- <a href="javascript:;" class="aa_2">美妆馆a>
- <a href="javascript:;" class="aa_2">家装城a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">母婴a>
- <a href="javascript:;" class="aa_2">食品a>
- <a href="javascript:;" class="aa_2">运动户外a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">农资频道a>
- <a href="javascript:;" class="aa_2">整车a>
- <a href="javascript:;" class="aa_2">图书a>
- p>
- li>
- <li>
- <h5>生活服务h5>
- <p>
- <a href="javascript:;" class="aa_2">京东众筹a>
- <a href="javascript:;" class="aa_2">白条a>
- <a href="javascript:;" class="aa_2">京东金融APPa>
- p>
- <p>
- <a href="javascript:;" class="aa_2">京东小金库a>
- <a href="javascript:;" class="aa_2">理财a>
- <a href="javascript:;" class="aa_2">智能家电a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">话费a>
- <a href="javascript:;" class="aa_2">水电煤a>
- <a href="javascript:;" class="aa_2">彩票a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">旅行a>
- <a href="javascript:;" class="aa_2">机票酒店a>
- <a href="javascript:;" class="aa_2">电影票a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">京东到家a>
- <a href="javascript:;" class="aa_2">京东众测a>
- <a href="javascript:;" class="aa_2">游戏a>
- p>
- li>
- <li style="border: 0;">
- <h5>更多精选h5>
- <p>
- <a href="javascript:;" class="aa_2">合作招商a>
- <a href="javascript:;" class="aa_2">京东通信a>
- <a href="javascript:;" class="aa_2">京东E卡a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">企业采购a>
- <a href="javascript:;" class="aa_2">服务市场a>
- <a href="javascript:;" class="aa_2">办公生活馆a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">乡村招募a>
- <a href="javascript:;" class="aa_2">校园加盟a>
- <a href="javascript:;" class="aa_2">京友邦a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">京东社区a>
- <a href="javascript:;" class="aa_2">智能社区a>
- <a href="javascript:;" class="aa_2">游戏社区a>
- p>
- <p>
- <a href="javascript:;" class="aa_2">知识产权维权a>
- <a href="javascript:;" class="aa_2">a>
- <a href="javascript:;" class="aa_2">a>
- p>
- li>
- ol>
- li>
- <li class="sjjd" style="border: 0;"><a href="javascript:;" class="aa">手机京东a>
- <div class="er">
- <div class="er_1">
- <div class="er_1_1">
- <h6><a href="#">手机京东a>h6>
- <p>新人专享大礼包p>
-
- div>
- div>
- <div class="er_1">
- <div class="er_1_1">
- <h6><a href="#">关注京东微信a>h6>
- <p>微信扫一扫关注新粉最高180元惊喜礼包p>
- div>
- div>
-
- <div class="er_1" style="border: 0;">
- <img src="/static/item/img/5874a555Ne8192324.jpg"/>
- <div class="er_1_1">
- <h6><a href="#">京东金融客户端a>h6>
- <p>新人专享大礼包p>
- <div><a href="#"><img src="/static/item/img/11.png"/>a><a href="#"><img src="/static/item/img/22.png"/>a>div>
- div>
- div>
- div>
- li>
- ul>
- div>
- header>
- <nav>
- <div class="nav_min">
- <div class="nav_top">
- <div class="nav_top_one"><a href="#"><img src="/static/item/img/111.png"/>a>div>
- <div class="nav_top_two"><input type="text"/><button>搜索button>div>
- <div class="nav_top_three"><a href="../JD_Shop/One_JDshop.html">我的购物车a><span class="glyphicon glyphicon-shopping-cart">span>
- <div class="nav_top_three_1">
- <img src="/static/item/img/44.png"/>购物车还没有商品,赶紧选购吧!
- div>
- div>
- div>
- <div class="nav_down">
- <ul class="nav_down_ul">
- <li class="nav_down_ul_1" style="width: 24%;float: left;"><a href="javascript:;">全部商品分类a>
-
- li>
- <li class="ul_li"><a href="javascript:;">服装城a>li>
- <li class="ul_li"><a href="javascript:;">美妆馆a>li>
- <li class="ul_li"><a href="javascript:;">超市a>li>
- <li class="ul_li" style="border-right: 1px solid lavender;"><a href="javascript:;">生鲜a>li>
- <li class="ul_li"><a href="javascript:;">全球购a>li>
- <li class="ul_li"><a href="javascript:;">闪购a>li>
- <li class="ul_li" style="border-right: 1px solid lavender;"><a href="javascript:;">拍卖a>li>
- <li class="ul_li"><a href="javascript:;">金融a>li>
- ul>
- div>
- div>
- nav>
-
- div>
-
-
- <div class="crumb-wrap">
- <div class="w">
- <div class="crumb">
- <div class="crumb-item">
- <a href="">手机a>
- div>
- <div class="crumb-item sep">>div>
- <div class="crumb-item">
- <a href="">手机通讯a>
- div>
- <div class="crumb-item sep">>div>
- <div class="crumb-item">
- <a href="">手机a>
- div>
- <div class="crumb-item sep">>div>
- <div class="crumb-item">
- <div class="crumb-item-one">
- 华为 (HUAWEI)
- <img src="/static/item/img/4a79b87a68623d4e8a73aff3e25fa99b.png" alt="" class="img" />
- <div class="crumb-item-two ">
- <div class="crumb-item-con clear">
- <ul class="con-ul">
- <li>
- <img src="/static/item/img/5825a5a6Nde8ecb75.jpg" alt="" />
- li>
- <li>
- <p>
- 荣耀8青春版 全网通标配 3GB+32GB 幻海蓝
- p>
- <p>
- ¥1099.00
- p>
- li>
- ul>
- <ul class="con-ul">
- <li>
- <img src="/static/item/img/5919637aN271a1301.jpg" alt="" />
- li>
- <li>
- <p>
- 荣耀8青春版 全网通标配 3GB+32GB 幻海蓝
- p>
- <p>
- ¥1099.00
- p>
- li>
- ul>
- <ul class="con-ul">
- <li>
- <img src="/static/item/img/599a806bN9d829c1c.jpg" alt="" />
- li>
- <li>
- <p>
- 荣耀8青春版 全网通标配 3GB+32GB 幻海蓝
- p>
- <p>
- ¥1099.00
- p>
- li>
- ul>
- div>
- <div class="crumb-item-cons clear">
- <ul>
- <li>华为(huawei)li>
- <li>小米(xiaomi)li>
- <li>APPleli>
- <li>魅族(meizu)li>
- <li>锤子li>
-
- ul>
- <ul>
- <li>三星li>
- <li>vivoli>
- <li>飞利浦li>
- <li>360li>
- <li>更多>>li>
-
- ul>
- div>
- div>
-
- div>
-
- div>
- <div class="crumb-item sep">>div>
- <div class="crumb-item">
- 华为Mate 10
- div>
- div>
-
- <div class="contact">
- <ul class="contact-ul">
- <li>
- <a href="#">
- 华为京东自营官方旗舰店
- a>
-
- <span class="contact-sp">
- <span class="contact-sp1">
- JD
- span>
- <span class="contact-sp2">
- 自营
- span>
- span>
- li>
- <li>
- <a href="#">
- <img src="/static/item/img/f5831b9848b32440b381bcd30a3d96c7.png" alt="" /> 联系供应商
- a>
- li>
- <li>
- <a href="#">
- <img src="/static/item/img/81a6326edc82d343a5a8860a6970f93b.png" alt="" /> JIMI
- a>
- li>
- <li>
- <a href="#">
- <img src="/static/item/img/a400e3d61d5645459f769b00d9f431e7.png" alt="" /> 关注店铺
- a>
- li>
- ul>
- <div class="contact-one">
- <ul>
- <li>客服li>
- <li><img src="/static/item/img/f5831b9848b32440b381bcd30a3d96c7.png" alt="" />留言li>
- <li><img src="/static/item/img/81a6326edc82d343a5a8860a6970f93b.png" alt="" />JIMI智能li>
- <li>
- <img src="/static/item/img/1466134037230.jpg" class="contact-img" />
- <p>手机下单p>
- li>
-
- ul>
- <div class="contact-two">
- <span><img src="/static/item/img/a400e3d61d5645459f769b00d9f431e7.png" alt="" />进店逛逛span>
- <span><img src="/static/item/img/a400e3d61d5645459f769b00d9f431e7.png" alt="" />关注店铺span>
- div>
- div>
- div>
-
- div>
- div>
- <div class="Shop">
- <div class="box">
- <div class="box-one ">
- <div class="boxx">
-
- <div class="imgbox">
- <div class="probox">
- <img class="img1" alt="" th:src="${item.info.skuDefaultImg}">
- <div class="hoverbox">div>
- div>
- <div class="showbox">
- <img class="img1" alt="" th:src="${item.info.skuDefaultImg}">
- div>
- div>
-
- <div class="box-lh">
-
- <div class="box-lh-one">
- <ul>
- <li th:each="img:${item.images}" th:if="${!#strings.isEmpty(img.imgUrl)}"><img th:src="${img.imgUrl}" />li>
- ul>
- div>
- <div id="left">
- < div>
- <div id="right">
- >
- div>
-
- div>
-
- <div class="boxx-one">
- <ul>
- <li>
- <span>
- <img src="/static/item/img/b769782fe4ecca40913ad375a71cb92d.png" alt="" />关注
- span>
- <span>
- <img src="/static/item/img/9224fcea62bfff479a6712ba3a6b47cc.png" alt="" />
- 对比
- span>
- li>
- <li>
-
- li>
- ul>
- div>
-
- div>
- <div class="box-two">
- <div class="box-name" th:text="${item.info.skuTitle}">
- 华为 HUAWEI Mate 10 6GB+128GB 亮黑色 移动联通电信4G手机 双卡双待
- div>
- <div class="box-hide" th:text="${item.info.skuSubtitle}">预订用户预计11月30日左右陆续发货!麒麟970芯片!AI智能拍照!
- <a href=""><u>u>a>
- div>
- <div class="box-yuyue">
- <div class="yuyue-one">
- <img src="/static/item/img/7270ffc3baecdd448958f9f5e69cf60f.png" alt="" /> 预约抢购
- div>
- <div class="yuyue-two">
- <ul>
- <li>
- <img src="/static/item/img/f64963b63d6e5849977ddd6afddc1db5.png" />
- <span>190103span> 人预约
- li>
- <li>
- <img src="/static/item/img/36860afb69afa241beeb33ae86678093.png" /> 预约剩余
- <span id="timer">
-
- span>
- li>
- ul>
- div>
- div>
- <div class="box-summary clear">
- <ul>
- <li>京东价li>
- <li>
- <span>¥span>
- <span th:text="${#numbers.formatDecimal(item.info.price,3,2)}">4499.00span>
- li>
- <li>
- 预约享资格
- li>
- <li>
- <a href="">
- 预约说明
- a>
- li>
- ul>
- div>
- <div class="box-wrap clear">
- <div class="box-wrap-one clear">
- <ul>
- <li>增值业务li>
- <li><img src="/static/item/img/90a6fa41d0d46b4fb0ff6907ca17c478.png" />li>
- <li><img src="/static/item/img/2e19336b961586468ef36dc9f7199d4f.png" />li>
- <li><img src="/static/item/img/1f80c3d6fabfd3418e54b005312c00b5.png" />li>
- ul>
- div>
- div>
-
- <div class="box-stock">
- <ul class="box-ul">
- <li>配送至li>
- <li class="box-stock-li">
- <div class="box-stock-one">
- 北京朝阳区管庄
- <img src="/static/item/img/4a79b87a68623d4e8a73aff3e25fa99b.png" alt="" class="img" />
- div>
- <div class="box-stock-two">
- <dl>
- <dt>
- <a>选择新地址a>
- <img src="/static/item/img/4a79b87a68623d4e8a73aff3e25fa99b.png" alt="" class="box-stock-two-img"/>
- dt>
- <dd>
- <div class="box-stock-dd">
- <div class="box-stock-top">
- <div class="box-stock-div">北京div>
- <div class="box-stock-div">朝阳区div>
- <div class="box-stock-div">管庄div>
- div>
- <div class="box-stock-fot">
- <div class="box-stock-con" style="display: block;">
- <ul>
- <li>北京li>
- <li>上海li>
- <li>天津li>
- <li>重庆li>
- ul>
- div>
- <div class="box-stock-con">
- <ul>
- <li>朝阳区li>
- <li>海淀区li>
- <li>东城区li>
- <li>西城区li>
- ul>
- div>
- <div class="box-stock-con">
- <ul>
- <li>4环到5环之内li>
- <li>管庄li>
- <li>北苑li>
- ul>
- div>
-
- div>
- div>
- dd>
- dl>
-
- div>
-
- li>
- <li>
- <span th:text="${item.hasStock?'有货':'无货'}">无货span>, 此商品暂时售完
- li>
- ul>
- div>
- <div class="box-supply">
- <ul class="box-ul">
- <li>li>
- <li>
- 由<span>京东span> 发货,并提供售后服务
- li>
- ul>
- div>
- <div class="box-attr-3">
- <div class="box-attr clear" th:each="attr:${item.saleAttr}">
- <dl>
- <dt>[[${attr.attrName}]]dt>
- <dd th:each="vals:${attr.attrValues}">
- <a class="sku_attr_value"
- th:attr="skus=${vals.skuIds},class=${#lists.contains(#strings.listSplit(vals.skuIds,','), item.info.skuId.toString())?'sku_attr_value checked':'sku_attr_value'}">
- [[${vals.attrValue}]]
- a>
- dd>
- dl>
- div>
- div>
-
- <div class="box-btns clear">
- <div class="box-btns-one">
- <input type="text" name="" id="" value="1" />
- <div class="box-btns-one1">
-
- <div>
- <button id="jia">
- +
- button>
- div>
- <div>
- <button id="jian">
- -
- button>
- div>
-
- div>
- div>
- <div class="box-btns-two">
- <a href="../商品分类\index.html">
- 立即预约
- a>
- div>
- <div class="box-btns-three">
- <img src="/static/item/img/e4ed3606843f664591ff1f68f7fda12d.png" alt="" /> 分享
- div>
- div>
-
- <div class="box-footer-zo">
- <div class="box-footer clear">
- <dl>
- <dt>本地活动dt>
- <dd>
- <a href="">
- ·1元500MB激活到账30元 >>
- a>
- dd>
- dl>
- div>
-
- <div class="box-footer">
- <dl>
- <dt>温馨提示dt>
- <dd>·本商品不能使用 东券 京券dd>
- <dd>·请完成预约后及时抢购!dd>
- dl>
- div>
- div>
- div>
-
- div>
- div>
-
- <div class="qianggoulioucheng">
- <div class="lioucheng">
- <h3>欲约抢购流程h3>
- div>
-
- <ul class="qianggoubuzhao">
- <li>
- <img src="/static/item/img/shop_03.png" />
- <dl class="buzhou">
- <dt>1.等待预约dt>
- <dl>预约即将开始dl>
- dl>
- li>
- <li>
- <img src="/static/item/img/shop_04.png" />
- <dl class="buzhou">
- <dt>2.预约中dt>
- <dl>2017-11-15 10:35 2017-11-15 23:59dl>
- dl>
- li>
- <li>
- <img src="/static/item/img/shop_05.png" />
- <dl class="buzhou">
- <dt>3.等待抢购dt>
- <dl>抢购即将开始dl>
- dl>
- li>
- <li>
- <img src="/static/item/img/shop_06.png" />
- <dl class="buzhou">
- <dt>4.抢购中dt>
- <dl>dl>
- dl>
- li>
- ul>
- div>
-
- <div class="ShopXiangqing">
- <div class="allLeft">
-
- <div class="huoreyuyue">
- <h3>火热预约h3>
- div>
- <div class="dangeshopxingqing">
- <ul class="shopdange">
- <li>
- <a href="##"><img src="/static/item/img/5a0afeddNb34732af.jpg" />a>
- <p>
- <a href="##">OPPO R11s Plus 双卡双待全面屏拍照手机香槟色 全网通(6G RAM+64G ROM)标配a>
- p>
- <p><strong class="J-p-20015341974">¥3699.00strong>p>
- li>
- <li>
- <a href="##"><img src="/static/item/img/5a12873eN41754123.jpg" />a>
- <p>
- <a target="_blank" title="詹姆士(GEMRY) R19plus全网通4G 智能手机 双卡双待 6+128GB 鳄鱼纹雅致版(新品预约)" href="//item.jd.com/20348283521.html">詹姆士(GEMRY) R19plus全网通4G 智能手机 双卡双待 6+128GB 鳄鱼纹雅致版(新品预约)a>
- p>
- <p><strong class="J-p-20348283521">¥13999.00strong>p>
- li>
- <li>
- <a href="##"><img src="/static/item/img/59ec0131Nf239df75.jpg" />a>
- <p>
- <a target="_blank" title="斐纳(TOMEFON) 德国家用无线无绳手持立式充电吸尘器 静音大吸力吸尘器TF-X60" href="//item.jd.com/16683419775.html">斐纳(TOMEFON) 德国家用无线无绳手持立式充电吸尘器 静音大吸力吸尘器TF-X60a>
- p>
- <p><strong class="J-p-16683419775">¥1599.00strong>p>
- li>
- <li>
- <a href="##"><img src="/static/item/img/59015444N27317512.jpg" />a>
- <p>
- <a target="_blank" title="斐纳(TOMEFON) 扫地机器人德国智能导航规划全自动超薄扫地机器人吸尘器TF-D60 香槟金" href="//item.jd.com/12187770381.html">斐纳(TOMEFON) 扫地机器人德国智能导航规划全自动超薄扫地机器人吸尘器TF-D60 香槟金a>
- p>
- <p><strong class="J-p-12187770381">¥2599.00strong>p>
- li>
- ul>
- div>
-
- <div class="huoreyuyue">
- <h3>看了又看h3>
- div>
- <div class="dangeshopxingqing">
- <ul class="shopdange">
- <li>
- <a href="##"><img src="/static/item/img/59e55e01N369f98f2.jpg" />a>
- <p>
- <a target="_blank" title="华为(HUAWEI) 华为 Mate10 4G手机 双卡双待 亮黑色 全网通(6GB RAM+128GB ROM)" href="//item.jd.com/17931625443.html">华为(HUAWEI) 华为 Mate10 4G手机 双卡双待 亮黑色 全网通(6GB RAM+128GB ROM)a>
- <p><strong class="J-p-17931625443">¥4766.00strong>p>
- li>
- <li>
- <a href="##"><img src="/static/item/img/584fcc3eNdb0ab94c.jpg" />a>
- <p>
- <a target="_blank" title="华为 Mate 9 Pro 6GB+128GB版 琥珀金 移动联通电信4G手机 双卡双待" href="//item.jd.com/3749093.html">华为 Mate 9 Pro 6GB+128GB版 琥珀金 移动联通电信4G手机 双卡双待a>
- p>
- <p><strong class="J-p-3749093">¥4899.00strong>p>
- li>
- <li>
-
- <a href="##"><img src="/static/item/img/59eb0df9Nd66d7585.jpg" />a>
- <p>
- <a target="_blank" title="华为(HUAWEI) 华为 Mate10 手机 亮黑色 全网通(4+64G)标准版" href="//item.jd.com/12306211773.html">华为(HUAWEI) 华为 Mate10 手机 亮黑色 全网通(4+64G)标准版a>
- p>
- <p><strong class="J-p-12306211773">¥4088.00strong>p>
- li>
- <li>
- <a href="##"><img src="/static/item/img/5a002ba3N126c2f73.jpg" />a>
- <p>
- <a target="_blank" title="斐纳(TOMEFON) 扫地机器人德国智能导航规划全自动超薄扫地机器人吸尘器TF-D60 香槟金" href="//item.jd.com/12187770381.html">斐纳(TOMEFON) 扫地机器人德国智能导航规划全自动超薄扫地机器人吸尘器TF-D60 香槟金a>
- p>
- <p><strong class="J-p-12187770381">¥2599.00strong>p>
- li>
- ul>
- <img src="/static/item/img/5a084a1aNa1aa0a71.jpg" />
- div>
- div>
-
- <div class="allquanbushop">
- <ul class="shopjieshao">
- <li class="jieshoa" style="background: #e4393c;">
- <a href="##" style="color: white;">商品介绍a>
- li>
- <li class="baozhuang">
- <a href="##">规格与包装a>
- li>
- <li class="baozhang">
- <a href="##">售后保障a>
- li>
- <li class="pingjia">
- <a href="##">商品评价(4万+)a>
- li>
- <li class="shuoming">
- <a href="##">预约说明a>
- li>
-
- ul>
- <button class="Lijiyuyuessss">
- 立即预约
- button>
- <ul class="shopjieshaos posi" style="display: none;">
- <li class="jieshoa" style="background: #e4393c;">
- <a href="#li1" style="color: white;">商品介绍a>
- li>
- <li class="baozhuang">
- <a href="#li2">规格与包装a>
- li>
- <li class="baozhang">
- <a href="#li3">售后保障a>
- li>
- <li class="pingjia">
- <a href="#li4">商品评价(4万+)a>
- li>
- <li class="shuoming">
- <a href="#li5">预约说明a>
- li>
- ul>
-
-
- <div class="huawei">
- <ul class="xuanxiangka">
- <li class="jieshoa actives" id="li1">
- <div class="shanpinsssss">
- <img class="xiaoguo" th:src="${desc}" th:each="desc:${#strings.listSplit(item.desc.decript,',')}" />
-
- div>
- li>
- <li class="baozhuang actives" id="li2">
- <div class="guiGebox">
- <div class="guiGe" th:each="group:${item.groupAttrs}">
- <h3 th:text="${group.groupName}">主体h3>
- <dl>
- <div th:each="attr:${group.attrs}">
- <dt th:text="${attr.attrName}">品牌dt>
- <dd th:text="${attr.attrValue}">华为(HUAWEI)dd>
- div>
- dl>
- div>
- div>
- li>
-
- <li class="baozhang actives" id="li3">
- <div class="oBox">
- <div class="shuoHou">
- <div class="baoZhang">
- <h2>售后保障h2>
- div>
- div>
-
- <div class="changJia">
- <div class="lianBao">
- <span class="oImg">
- <img src="/static/item/img/2017.jpg" alt="" />
- <h3>厂家服务h3>
- span>
- <div class="wenZi">
- 本产品全国联保,享受三包服务,质保期为:一年保<br />
- 如因质量问题或故障,凭厂商维修中心或特约维修点的质量检测证明,享受7日内退货,15日内换货,15日以上在保质期内享受免费保修等安保服务!<br />
- (注:如厂家在商品介绍中有售后保障的说明,则此商品按照厂家说明执行售后保障服务。)您可以查询本品牌在各地售后服务中心的练习方式<a href="#">请点击这儿查询...a><br /><br />
- div>
- div>
- <div class="lianBao oCn">
- <span class="oImg">
- <img src="/static/item/img/2017.jpg" alt="" />
- <h3>京东承诺h3>
- span>
- <div class="wenZi">
- 本产品全国联保,享受三包服务,质保期为:一年保<br />
- 如因质量问题或故障,凭厂商维修中心或特约维修点的质量检测证明,享受7日内退货,15日内换货,15日以上在保质期内享受免费保修等安保服务!<br />
- (注:如厂家在商品介绍中有售后保障的说明,则此商品按照厂家说明执行售后保障服务。)您可以查询本品牌在各地售后服务中心的练习方式<a href="#">请点击这儿查询...a><br /><br /><br />
- div>
- div>
-
- <div class="lianBao ">
- <span class="oImg">
- <img src="/static/item/img/2017.jpg" alt="" />
- <h3>正品行货h3>
- span>
- <div class="wenZi hangHuo">
- 京东商城向您保证所售商品均为正品行货,京东自营商品开具机打发票或电子发票。
- div>
- div>
- <div class="lianBao quanGuo">
- <span class="oImg">
- <img src="/static/item/img/2017-1.jpg" alt="" />
- <h3>全国联保h3>
- span>
- <div class="wenZi">
- 凭质保证书及京东商城发票,可享受全国联保服务(奢侈品、钟表除外;奢侈品、钟表由京东联系保修,享受法定三包售后服务),与您亲临商场选购的商品享受相同的质量保证。京东商城还为您提供具有竞争力的商品价格和运费政策,请您放心购买! <br />
-
- 注:因厂家会在没有任何提前通知的情况下更改产品包装、产地或者一些附件,本司不能确保客户收到的货物与商城图片、产地、附件说明完全一致。只能确保为原厂正货!并且保证与当时市场上同样主流新品一致。若本商城没有及时更新,请大家谅解!
- div>
- div>
-
- <div class="quanLi">
- <h4>权利声明:h4>
- <div class="jingDong">
- 京东上的所有商品信息、客户评价、商品咨询、网友讨论等内容,是京东重要的经营资源,未经许可,禁止非法转载使用。<br />
- <span class="oZhu">注span>:本站商品信息均来自于合作方,其真实性、准确性和合法性由信息拥有者(合作方)负责。本站不提供任何保证,并不承担任何法律责任。
- div>
- div>
- <div class="quanLi jiaGe">
- <h4>价格说明:h4>
- <div class="jingDong">
- <span class="oZhu">京东价span>:京东价为商品的销售价,是您最终决定是否购买商品的依据。<br />
- <span class="oZhu">划线价span>:商品展示的划横线价格为参考价,该价格可能是品牌专柜标价、商品吊牌价或由品牌供应商提供的正品零售价(如厂商指导价、建议零售价等)或该商品在京东平台上曾经展示过的销售价;由于地区、时间的差异性和市场行情波动,品牌专柜标价、商品吊牌价等可能会与您购物时展示的不一致,该价格仅供您参考。<br />
- <span class="oZhu">折扣span>:如无特殊说明,折扣指销售商在原价、或划线价(如品牌专柜标价、商品吊牌价、厂商指导价、厂商建议零售价)等某一价格基础上计算出的优惠比例或优惠金额;如有疑问,您可在购买前联系销售商进行咨询。<br />
- <span class="oZhu">异常问题span>:商品促销信息以商品详情页“促销”栏中的信息为准;商品的具体售价以订单结算页价格为准;如您发现活动商品售价或促销信息有异常,建议购买前先联系销售商咨询。
- div>
- div>
- div>
-
-
- div>
- li>
-
- <li class="PINgjia actives" id="li4">
- <div class="h3">
- <h3>商品评价h3>
- div>
- <div class="nav">
- <div class="left">
- <p class="haoping">好评度p>
- <p><span>100%span>p>
- div>
- <div class="right">
- <ul>
- <li>
- <a href="##">就是快(424)a>
- li>
- <li>
- <a href="##">物流很快(254) a>
- li>
- <li>
- <a href="##">货真价实(168)a>
- li>
- <li>
- <a href="##">有档次(158)a>
- li>
- <li>
- <a href="##">国产品牌(133)a>
- li>
- <li>
- <a href="##">外形美观(103)a>
- li>
- <li>
- <a href="##">很给力(75)a>
- li>
- <li>
- <a href="##">反应灵敏(68)a>
- li>
- <li>
- <a href="##">性价比高(60)a>
- li>
- <li>
- <a href="##">价格优惠(50)a>
- li>
- <li>
- <a href="##">功能齐全(49)a>
- li>
- <li style="background: gainsboro;">
- <a href="##">速度太慢(5)a>
- ul>
- div>
- div>
-
- <div class="allpingjia">
- <ul>
- <li><a href="##">全部评价(4.2万)a>li>
- <li><a href="##">晒图(500)a>li>
- <li><a href="##">追拼(200+)a>li>
- <li><a href="##">好评(4.1万)a>li>
- <li><a href="##">中评(100+)a>li>
- <li><a href="##">差评(100+)a>li>
- <li><a href="##"><input type="checkbox"/>只看当前商品价格a>li>
- <li class="imga" style="float: right;"><a href="##">推荐排序 <img src="/static/item/img/animaite.png"/> a>
- li>
- ul>
- div>
- li>
- <li class="shuoming actives" id="li5">li>
- ul>
- div>
- div>
- div>
- div>
- <div class="headera">
- <div class="Logo-tu">
- <span><img src="/static/item/img/service_items_1.png"/>span>
- <span><img src="/static/item/img/service_items_2.png"/>span>
- <span><img src="/static/item/img/service_items_3.png"/>span>
- <span><img src="/static/item/img/service_items_4.png"/>span>
- div>
- <div class="table">
- <dl>
- <dt><a href="##">购物指南a>dt>
- <dd>
- <a href="##">购物流程a>
- dd>
- <dd>
- <a href="##">会员介绍a>
- dd>
- <dd>
- <a href="##">生活旅行/团购a>
- dd>
- <dd>
- <a href="##">常见问题a>
- dd>
- <dd>
- <a href="##">大家电a>
- dd>
- <dd>
- <a href="##">练习客服a>
- dd>
- dl>
- <dl>
- <dt><a href="##">配送方式a>dt>
- <dd>
- <a href="##">上门自提a>
- dd>
- <dd>
- <a href="##">211限时达a>
- dd>
- <dd>
- <a href="##">配送服务查询a>
- dd>
- <dd>
- <a href="##">a>
- dd>
- <dd>
- <a href="##">海外配送a>
- dd>
- <dd>dd>
- dl>
- <dl>
- <dt><a href="##">支付方式a>dt>
- <dd>
- <a href="##">货到付款a>
- dd>
- <dd>
- <a href="##">在线支付a>
- dd>
- <dd>
- <a href="##">分期付款a>
- dd>
- <dd>
- <a href="##">邮局汇款a>
- dd>
- <dd>
- <a href="##">公司转账a>
- dd>
- <dd>dd>
- dl>
- <dl>
- <dt><a href="##">售后服务a>dt>
- <dd>
- <a href="##">售后政策a>
- dd>
- <dd>
- <a href="##">价格保护a>
- dd>
- <dd>
- <a href="##">退款说明a>
- dd>
- <dd>
- <a href="##">返修/退换货a>
- dd>
- <dd>
- <a href="##">取消订单a>
- dd>
- <dd>dd>
- dl>
- <dl class="dls">
- <dt><a href="##">特色服务a>dt>
- <dd>
- <a href="##">夺宝岛a>
- dd>
- <dd>
- <a href="##">DIY装机a>
- dd>
- <dd>
- <a href="##">延保服务a>
- dd>
- <dd>
- <a href="##">京东E卡a>
- dd>
- <dd>
- <a href="##">京东通信a>
- dd>
- <dd>
- <a href="##">京东JD+a>
- dd>
- dl>
- div>
-
- <div class="guanyuwomen">
- <ul>
- <li>
- <a href="##">关于我们a>
- li>
- <li>|li>
- <li>
- <a href="##">联系我们a>
- li>
- <li>|li>
- <li>
- <a href="##">联系客服a>
- li>
- <li>|li>
- <li>
- <a href="##">合作招商a>
- li>
- <li>|li>
- <li>
- <a href="##">商家帮助a>
- li>
- <li>|li>
- <li>
- <a href="##">营销中心a>
- li>
- <li>|li>
- <li>
- <a href="##">手机京东a>
- li>
- <li>|li>
- <li>
- <a href="##">友情链接a>
- li>
- <li>|li>
- <li>
- <a href="##">销售联盟a>
- li>
- <li>|li>
- <li>
- <a href="##">京东社区a>
- li>
- <li>|li>
- <li>
- <a href="##">风险检测a>
- li>
- <li>|li>
- <li>
- <a href="##">隐私政策a>
- li>
- <li>|li>
- <li>
- <a href="##">京东公益a>
- li>
- <li>|li>
- <li>
- <a href="##">English Sitea>
- li>
- <li>|li>
- <li>
- <a href="##">Mdeila $ IRa>
- li>
- ul>
- div>
-
- <p class="p1"><img src="/static/item/img/56a0a994Nf1b662dc.png" />
- <a href="##"> 京公网安备 11000002000088号a>|
- <a href="##"> 京ICP证070359号a>|
- <a href="##"> 互联网药品信息服务资格证编号(京)-经营性-2014-0008 a>|
- <a href="##">新出发京零 字第大120007号a>
- p>
- <p class="p1">
- <a href="##"> 互联网出版许可证编号新出网证(京)字150号a>|
- <a href="##"> 出版物经营许可证a>|
- <a href="##"> 网络文化经营许可证京网文 a>|
- <a href="##">[2014]2148-348号 a>|
- <a href="##"> 违法和不良信息举报电话 a>|
- <a href="##">:4006561155 a>
- p>
- <p class="p1">
- <a href="##"> Copyright © 2004-2017 京东JD.com 版权所有a>|
- <a href="##"> 消费者维权热线:4006067733 经营证照a>|
- p>
- <p class="p1">
- <a href="##"> 京东旗下网站:京东支付a>|
- <a href="##"> 京东云a>
- p>
- <p class="p3">
- <img src="/static/item/img/54b8871eNa9a7067e.png" />
- <img src="/static/item/img/54b8872dNe37a9860.png" />
- <img src="/static/item/img/54b8875fNad1e0c4c.png" />
- <img src="/static/item/img/5698dc03N23f2e3b8.jpg" />
- <img src="/static/item/img/5698dc16Nb2ab99df.jpg" />
- <img src="/static/item/img/56a89b8fNfbaade9a.jpg" />
- p>
- div>
- <div class="Fixedbian">
- <ul>
- <li class="li1"><a class="aaa" href="##">顶部a>li>
- ul>
- div>
- <div class="gouwuchexiaguo">
- <img src="/static/item/img/44.png" />
- <span>购物车还没有商品,赶紧选购吧!span>
- div>
- body>
-
- <script src="/static/item/js/jquery1.9.js" type="text/javascript" charset="utf-8">script>
- <script src="/static/item/js/js.js" type="text/javascript" charset="utf-8">script>
- <script>
- $(".sku_attr_value").click(function (){
- // 1. 点击的元素先添加上自定义的属性。为了识别我们是刚才被点击的
- var skus = new Array();
- $(this).addClass("clicked");
- var curr = $(this).attr("skus").split(",");
- skus.push(curr);
- // 2. 去掉同一行所有的checked
- $(this).parent().parent().find(".sku_attr_value").removeClass("checked");
- // 3. 找到其他被选中的属性
- $("a[class='sku_attr_value checked']").each(function (){
- skus.push($(this).attr("skus").split(","));
- });
- // 4. 使用filter取出他们的交集,得到skuId
- var filterEle = skus[0];
- for(var i=1 ;i
length ;i++){ - filterEle = $(filterEle).filter(skus[i]);
- }
- console.log(filterEle[0])
- location.href = "http://item.gulimall.com/"+filterEle[0]+".html";
- });
- $(function (){
- $(".sku_attr_value").parent().css({"border":"solid 1px #CCC"});
- $("a[class='sku_attr_value checked']").parent().css({"border":"solid 1px red"})
- })
- script>
-
- html>
所有的操作针对于商品服务gulimall-product。
spring-boot-configuration-processor作用:你自己创建的配置类生成元数据信息,这样就能在你自己的配置文件中显示出来非常的方便。【可以不加】
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-configuration-processorartifactId>
- <optional>trueoptional>
- dependency>
引入以上依赖,配置文件中会显示:
gulimall-product/src/main/java/com/wen/gulimall/product/config/ThreadPoolConfigProperties.java
- @Data
- @Component
- @ConfigurationProperties(prefix = "gulimall.thread")
- public class ThreadPoolConfigProperties {
- private Integer coreSize;
- private Integer maxSize;
- private Integer keepAliveTime;
- }
- gulimall:
- thread:
- core-size: 20
- max-size: 200
- keep-alive-time: 10
gulimall-product/src/main/java/com/wen/gulimall/product/config/MyThreadConfig.java
- /**
- * @description 线程池配置
- * 注意:线程池属性类ThreadPoolConfigProperties已经使用了@Component放入容器中,
- * 不需要在使用@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
- */
- //@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
- @Configuration
- public class MyThreadConfig {
-
- @Bean
- public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties poolProperties){
- return new ThreadPoolExecutor(poolProperties.getCoreSize(),
- poolProperties.getMaxSize(),
- poolProperties.getKeepAliveTime(),
- TimeUnit.SECONDS,
- new LinkedBlockingQueue<>(100000),
- Executors.defaultThreadFactory(),
- new ThreadPoolExecutor.AbortPolicy());
-
- }
- }
- @Controller
- public class ItemController {
- @Resource
- private SkuInfoService skuInfoService;
-
- @GetMapping("/{skuId}.html")
- public String item(@PathVariable Long skuId, Model model){
- // 获取sku的基本信息 pms_sku_info
- // 获取sku的图片信息 pms_sku_images
- // 获取spu的销售属性组合
- // 获取spu的介绍
- // 获取spu的规格参数信息
- SkuItemVo vo = null;
- try {
- vo = skuInfoService.item(skuId);
- } catch (ExecutionException e) {
- e.printStackTrace();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- model.addAttribute("item",vo);
- return "item";
- }
- }
- @Service("skuInfoService")
- public class SkuInfoServiceImpl extends ServiceImpl
implements SkuInfoService { -
- @Resource
- private SkuImagesService skuImagesService;
- @Resource
- private SpuInfoDescService spuInfoDescService;
- @Resource
- private AttrGroupService attrGroupService;
- @Resource
- private SkuSaleAttrValueService skuSaleAttrValueService;
- @Resource
- private ThreadPoolExecutor threadPoolExecutor;
-
- ...
-
- @Override
- public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
- SkuItemVo skuItemVo = new SkuItemVo();
-
- // 1.获取sku的基本信息 pms_sku_info
- CompletableFuture
infoFuture = CompletableFuture.supplyAsync(() -> { - SkuInfoEntity info = getById(skuId);
- skuItemVo.setInfo(info);
- return info;
- }, threadPoolExecutor);
-
- CompletableFuture
saleAttrFuture = infoFuture.thenAcceptAsync((res) -> { - // 3.获取spu的销售属性组合
- List
saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId()); - skuItemVo.setSaleAttr(saleAttrVos);
- }, threadPoolExecutor);
-
- CompletableFuture
descFuture = infoFuture.thenAcceptAsync(res -> { - // 4.获取spu的介绍
- SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());
- skuItemVo.setDesc(spuInfoDescEntity);
- }, threadPoolExecutor);
-
- CompletableFuture
baseAttrFuture = infoFuture.thenAcceptAsync(res -> { - // 5.获取spu的规格参数信息
- List
attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId()); - skuItemVo.setGroupAttrs(attrGroupVos);
- }, threadPoolExecutor);
-
- CompletableFuture
imageFuture = CompletableFuture.runAsync(() -> { - // 2.获取sku的图片信息 pms_sku_images
- List
images = skuImagesService.getImagesBySkuId(skuId); - skuItemVo.setImages(images);
- }, threadPoolExecutor);
-
- // 等待所有任务都完成,不用写infoFuture,因为saleAttrFuture/descFuture/baseAttrFuture他们依赖infoFuture完成的结果
- CompletableFuture.anyOf(saleAttrFuture,descFuture,baseAttrFuture,imageFuture).get();
-
- return skuItemVo;
- }
-
- }