如何使用Spring开发和监控线程池服务

来源:互联网 发布:淘宝未发货算退款率吗 编辑:程序博客网 时间:2024/05/17 19:16

线程池对执行同步或异步的任务很重要。本文展示如何利用Spring开发并监控线程池服务。创建线程池的其他两种方法已讲解过。

使用技术

  • JDK 1.6.0_21
  • Spring 3.0.5
  • Maven 3.0.2

第1步:创建Maven工程

下面是一个maven工程。(可以使用Maven或IDE的插件创建)。

第2步:添加依赖库

将Spring的依赖添加到Maven的pom.xml文件中。

1
2
3
4
5
6
7
8
9
10
11
<!-- Spring 3 dependencies -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
</dependency>

使用下面的插件创建可执行jar包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>1.3.1</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>com.otv.exe.Application</mainClass>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.handlers</resource>
                    </transformer>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                        <resource>META-INF/spring.schemas</resource>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

第3步:创建任务类

创建一个实现Runnable接口的新TestTask类。这个类表示要执行的任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.otv.task;
 
import org.apache.log4j.Logger;
 
/**
 * @author onlinetechvision.com
 * @since 17 Oct 2011
 * @version 1.0.0
 *
 */
public class TestTask implementsRunnable {
 
    privatestatic Logger log = Logger.getLogger(TestTask.class);
    String taskName;
 
    publicTestTask() {
    }
 
    publicTestTask(String taskName) {
        this.taskName = taskName;
    }
 
    publicvoid run() {
        try{
            log.debug(this.taskName +" : is started.");
            Thread.sleep(10000);
            log.debug(this.taskName +" : is completed.");
        }catch (InterruptedException e) {
            log.error(this.taskName +" : is not completed!");
            e.printStackTrace();
        }      
    }
 
    @Override
    publicString toString() {
        return(getTaskName());
    }
 
    publicString getTaskName() {
        returntaskName;
    }
 
    publicvoid setTaskName(String taskName) {
        this.taskName = taskName;
    }
}

第4步:创建TestRejectedExecutionHandler类

TestRejectedExecutionHandler类实现了RejectedExecutionHandler接口。如果没有空闲线程并且队列超出限制,任务会被拒绝。这个类处理被拒绝的任务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.otv.handler;
 
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
 
import org.apache.log4j.Logger;
 
/**
 * @author onlinetechvision.com
 * @since 17 Oct 2011
 * @version 1.0.0
 *
 */
public class TestRejectedExecutionHandler implementsRejectedExecutionHandler {
 
    privatestatic Logger log = Logger.getLogger(TestRejectedExecutionHandler.class);
 
    publicvoid rejectedExecution(Runnable runnable, ThreadPoolExecutor executor) {
        log.debug(runnable.toString() +" : has been rejected");
    }
}

第5步:创建ITestThreadPoolExecutorService接口

创建ITestThreadPoolExecutorService接口。(译者注:这个接口的主要功能是通过设置的参数创建一个线程池)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package com.otv.srv;
 
import java.util.concurrent.ThreadPoolExecutor;
 
import com.otv.handler.TestRejectedExecutionHandler;
 
/**
 * @author onlinetechvision.com
 * @since 17 Oct 2011
 * @version 1.0.0
 *
 */
public interface ITestThreadPoolExecutorService {
 
    publicThreadPoolExecutor createNewThreadPool();
 
    publicint getCorePoolSize();
 
    publicvoid setCorePoolSize(intcorePoolSize);
 
    publicint getMaxPoolSize();
 
    publicvoid setMaxPoolSize(intmaximumPoolSize);
 
    publiclong getKeepAliveTime();
 
    publicvoid setKeepAliveTime(longkeepAliveTime);
 
    publicint getQueueCapacity();
 
    publicvoid setQueueCapacity(intqueueCapacity);
 
    publicTestRejectedExecutionHandler getTestRejectedExecutionHandler();
 
    publicvoid setTestRejectedExecutionHandler(TestRejectedExecutionHandler testRejectedExecutionHandler);
 
}

第6步:创建TestThreadPoolExecutorService类

TestThreadPoolExecutorService类实现了ITestThreadPoolExecutorService接口(上一步创建的接口)。这个类可以创建一个新的线程池。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.otv.srv;
 
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
 
import com.otv.handler.TestRejectedExecutionHandler;
 
/**
 * @author onlinetechvision.com
 * @since 17 Oct 2011
 * @version 1.0.0
 *
 */
public class TestThreadPoolExecutorService implementsITestThreadPoolExecutorService {
 
    privateint  corePoolSize;
    privateint  maxPoolSize;
    privatelong keepAliveTime;
    privateint  queueCapacity;
    TestRejectedExecutionHandler testRejectedExecutionHandler;
 
    publicThreadPoolExecutor createNewThreadPool() {
        ThreadPoolExecutor executor =new ThreadPoolExecutor(getCorePoolSize(),
                                                                getMaxPoolSize(),
                                                                getKeepAliveTime(),
                                                                TimeUnit.SECONDS,
                                                                newArrayBlockingQueue(getQueueCapacity()),
                                                                getTestRejectedExecutionHandler());
        returnexecutor;
    }
 
    publicint getCorePoolSize() {
        returncorePoolSize;
    }
 
    publicvoid setCorePoolSize(intcorePoolSize) {
        this.corePoolSize = corePoolSize;
    }
 
    publicint getMaxPoolSize() {
        returnmaxPoolSize;
    }
 
    publicvoid setMaxPoolSize(intmaxPoolSize) {
        this.maxPoolSize = maxPoolSize;
    }
 
    publiclong getKeepAliveTime() {
        returnkeepAliveTime;
    }
 
    publicvoid setKeepAliveTime(longkeepAliveTime) {
        this.keepAliveTime = keepAliveTime;
    }
 
    publicint getQueueCapacity() {
        returnqueueCapacity;
    }
 
    publicvoid setQueueCapacity(intqueueCapacity) {
        this.queueCapacity = queueCapacity;
    }
 
    publicTestRejectedExecutionHandler getTestRejectedExecutionHandler() {
        returntestRejectedExecutionHandler;
    }
 
    publicvoid setTestRejectedExecutionHandler(TestRejectedExecutionHandler testRejectedExecutionHandler) {
        this.testRejectedExecutionHandler = testRejectedExecutionHandler;
    }
}

第7步: 创建IThreadPoolMonitorService接口

创建IThreadPoolMonitorService接口

1
2
3
4
5
6
7
8
9
10
11
12
package com.otv.monitor.srv;
 
import java.util.concurrent.ThreadPoolExecutor;
 
public interface IThreadPoolMonitorService extendsRunnable {
 
    publicvoid monitorThreadPool();
 
    publicThreadPoolExecutor getExecutor();
 
    publicvoid setExecutor(ThreadPoolExecutor executor);
}

第8步:创建ThreadPoolMonitorService类

ThreadPoolMonitorService类实现了IThreadPoolMonitorService接口。这个类用来监控已创建的线程池。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
package com.otv.monitor.srv;
 
import java.util.concurrent.ThreadPoolExecutor;
import org.apache.log4j.Logger;
 
/**
 * @author onlinetechvision.com
 * @since 17 Oct 2011
 * @version 1.0.0
 *
 */
public class ThreadPoolMonitorService implementsIThreadPoolMonitorService {
 
    privatestatic Logger log = Logger.getLogger(ThreadPoolMonitorService.class);
    ThreadPoolExecutor executor;
    privatelong monitoringPeriod;
 
    publicvoid run() {
        try{
            while(true){
                monitorThreadPool();
                Thread.sleep(monitoringPeriod*1000);
            }
        }catch (Exception e) {
            log.error(e.getMessage());
        }
    }
 
    publicvoid monitorThreadPool() {
        StringBuffer strBuff =new StringBuffer();
        strBuff.append("CurrentPoolSize : ").append(executor.getPoolSize());
        strBuff.append(" - CorePoolSize : ").append(executor.getCorePoolSize());
        strBuff.append(" - MaximumPoolSize : ").append(executor.getMaximumPoolSize());
        strBuff.append(" - ActiveTaskCount : ").append(executor.getActiveCount());
        strBuff.append(" - CompletedTaskCount : ").append(executor.getCompletedTaskCount());
        strBuff.append(" - TotalTaskCount : ").append(executor.getTaskCount());
        strBuff.append(" - isTerminated : ").append(executor.isTerminated());
 
        log.debug(strBuff.toString());
    }
 
    publicThreadPoolExecutor getExecutor() {
        returnexecutor;
    }
 
    publicvoid setExecutor(ThreadPoolExecutor executor) {
        this.executor = executor;
    }  
 
    publiclong getMonitoringPeriod() {
        returnmonitoringPeriod;
    }
 
    publicvoid setMonitoringPeriod(longmonitoringPeriod) {
        this.monitoringPeriod = monitoringPeriod;
    }
}

第9步:创建Starter类

(译者注:这个类内部维护了一个线程池服务(testThreadPoolExecutorService)和一个监控服务(threadPoolMonitorService),然后创建线程池、启动一个单独的线程执行监控服务、通过线程池执行任务)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.otv.start;
 
import java.util.concurrent.ThreadPoolExecutor;
 
import org.apache.log4j.Logger;
 
import com.otv.handler.TestRejectedExecutionHandler;
import com.otv.monitor.srv.IThreadPoolMonitorService;
import com.otv.monitor.srv.ThreadPoolMonitorService;
import com.otv.srv.ITestThreadPoolExecutorService;
import com.otv.srv.TestThreadPoolExecutorService;
import com.otv.task.TestTask;
 
/**
 * @author onlinetechvision.com
 * @since 17 Oct 2011
 * @version 1.0.0
 *
 */
public class Starter {
 
    privatestatic Logger log = Logger.getLogger(TestRejectedExecutionHandler.class);
 
    IThreadPoolMonitorService threadPoolMonitorService;
    ITestThreadPoolExecutorService testThreadPoolExecutorService;
 
    publicvoid start() {
 
        // A new thread pool is created...
        ThreadPoolExecutor executor = testThreadPoolExecutorService.createNewThreadPool();
        executor.allowCoreThreadTimeOut(true);
 
        // Created executor is set to ThreadPoolMonitorService...
        threadPoolMonitorService.setExecutor(executor);
 
        // ThreadPoolMonitorService is started...
        Thread monitor =new Thread(threadPoolMonitorService);
        monitor.start();
 
        // New tasks are executed...
        for(inti=1;i&lt;10;i++) {
            executor.execute(newTestTask(&quot;Task&quot;+i));
        }
 
        try{
            Thread.sleep(40000);
        }catch (Exception e)   {
            log.error(e.getMessage());
        }
 
        for(inti=10;i&lt;19;i++) {
            executor.execute(newTestTask(&quot;Task&quot;+i));
        }
 
        // executor is shutdown...
        executor.shutdown();
    }  
 
    publicIThreadPoolMonitorService getThreadPoolMonitorService() {
        returnthreadPoolMonitorService;
    }
 
    publicvoid setThreadPoolMonitorService(IThreadPoolMonitorService threadPoolMonitorService) {
        this.threadPoolMonitorService = threadPoolMonitorService;
    }
 
    publicITestThreadPoolExecutorService getTestThreadPoolExecutorService() {
        returntestThreadPoolExecutorService;
    }
 
    publicvoid setTestThreadPoolExecutorService(ITestThreadPoolExecutorService testThreadPoolExecutorService) {
        this.testThreadPoolExecutorService = testThreadPoolExecutorService;
    }
}

第10步:创建Application类

创建Application类。这个类运行应用程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.otv.start;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
/**
 * @author onlinetechvision.com
 * @since 17 Oct 2011
 * @version 1.0.0
 *
 */
public class Application {
 
    publicstatic void main(String[] args) {
       ApplicationContext context =new ClassPathXmlApplicationContext(&quot;applicationContext.xml&quot;);
       Starter starter = (Starter) context.getBean(&quot;Starter&quot;);
       starter.start();
    }
}

第11步:创建applicationContext.xml文件

(译者注:在Spring中注册了上面所创建的类,并提前设置了部分相应的参数,比如将监控服务的监控周期设为5)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<beansxmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
    <!-- Beans Declaration -->
    <beanid="TestTask"class="com.otv.task.TestTask"></bean>
    <beanid="ThreadPoolMonitorService"class="com.otv.monitor.srv.ThreadPoolMonitorService">
        <propertyname="monitoringPeriod" value="5"/>
    </bean>
    <beanid="TestRejectedExecutionHandler"class="com.otv.handler.TestRejectedExecutionHandler"></bean>
    <beanid="TestThreadPoolExecutorService"class="com.otv.srv.TestThreadPoolExecutorService">
        <propertyname="corePoolSize" value="1"/>
        <propertyname="maxPoolSize"  value="3"/>
        <propertyname="keepAliveTime"value="10"/>
        <propertyname="queueCapacity"value="3"/>
        <propertyname="testRejectedExecutionHandler"ref="TestRejectedExecutionHandler"/>
    </bean>
    <beanid="Starter"class="com.otv.start.Starter">
        <propertyname="threadPoolMonitorService"ref="ThreadPoolMonitorService"/>
        <propertyname="testThreadPoolExecutorService"ref="TestThreadPoolExecutorService"/>
    </bean>
</beans>

第12步:创建线程池的另一方法

Spring提供的ThreadPoolTaskExecutor类也可以创建线程池。

(译者注:上面通过我们自己创建的TestThreadPoolExecutorService类来设置线程池的各项参数并创建线程池,但实际上Spring也提供了功能类似的类,就是ThreadPoolTaskExecutor。所以也可以使用这种方式创建线程池)

1
2
3
4
5
6
7
8
9
<beanid="threadPoolTaskExecutor"class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  <propertyname="corePoolSize" value="1"/>
  <propertyname="maxPoolSize"  value="3"/>
  <propertyname="queueCapacity"value="3"/>
</bean>
 
<beanid="testTaskExecutor"class="TestTaskExecutor">
  <constructor-argref="threadPoolTaskExecutor"/>
</bean>

第13步:构建项目

OTV_Spring_ThreadPool工程被build后,就会产生一个OTV_Spring_ThreadPool-0.0.1-SNAPSHOT.jar包。

第14步:运行工程

OTV_Spring_ThreadPool-0.0.1-SNAPSHOT.jar运行后,输出日志如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
18.10.201120:08:48DEBUG (TestRejectedExecutionHandler.java:19) - Task7 : has been rejected
18.10.201120:08:48DEBUG (TestRejectedExecutionHandler.java:19) - Task8 : has been rejected
18.10.201120:08:48DEBUG (TestRejectedExecutionHandler.java:19) - Task9 : has been rejected
18.10.201120:08:48DEBUG (TestTask.java:25) - Task1 : is started.
18.10.201120:08:48DEBUG (TestTask.java:25) - Task6 : is started.
18.10.201120:08:48DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :2 - CompletedTaskCount :0 - TotalTaskCount :5 - isTerminated :false
18.10.201120:08:48DEBUG (TestTask.java:25) - Task5 : is started.
18.10.201120:08:53DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :3 - CompletedTaskCount :0 - TotalTaskCount :6 - isTerminated :false
18.10.201120:08:58DEBUG (TestTask.java:27) - Task6 : is completed.
18.10.201120:08:58DEBUG (TestTask.java:27) - Task1 : is completed.
18.10.201120:08:58DEBUG (TestTask.java:25) - Task3 : is started.
18.10.201120:08:58DEBUG (TestTask.java:25) - Task2 : is started.
18.10.201120:08:58DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :3 - CompletedTaskCount :2 - TotalTaskCount :6 - isTerminated :false
18.10.201120:08:58DEBUG (TestTask.java:27) - Task5 : is completed.
18.10.201120:08:58DEBUG (TestTask.java:25) - Task4 : is started.
18.10.201120:09:03DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :3 - CompletedTaskCount :3 - TotalTaskCount :6 - isTerminated :false
18.10.201120:09:08DEBUG (TestTask.java:27) - Task2 : is completed.
18.10.201120:09:08DEBUG (TestTask.java:27) - Task3 : is completed.
18.10.201120:09:08DEBUG (TestTask.java:27) - Task4 : is completed.
18.10.201120:09:08DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :0 - CompletedTaskCount :6 - TotalTaskCount :6 - isTerminated :false
18.10.201120:09:13DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :0 - CompletedTaskCount :6 - TotalTaskCount :6 - isTerminated :false
18.10.201120:09:18DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :0 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :0 - CompletedTaskCount :6 - TotalTaskCount :6 - isTerminated :false
18.10.201120:09:23DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :0 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :0 - CompletedTaskCount :6 - TotalTaskCount :6 - isTerminated :false
18.10.201120:09:28DEBUG (TestTask.java:25) - Task10 : is started.
18.10.201120:09:28DEBUG (TestRejectedExecutionHandler.java:19) - Task16 : has been rejected
18.10.201120:09:28DEBUG (TestRejectedExecutionHandler.java:19) - Task17 : has been rejected
18.10.201120:09:28DEBUG (TestRejectedExecutionHandler.java:19) - Task18 : has been rejected
18.10.201120:09:28DEBUG (TestTask.java:25) - Task14 : is started.
18.10.201120:09:28DEBUG (TestTask.java:25) - Task15 : is started.
18.10.201120:09:28DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :3 - CompletedTaskCount :6 - TotalTaskCount :12 - isTerminated :false
18.10.201120:09:33DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :3 - CompletedTaskCount :6 - TotalTaskCount :12 - isTerminated :false
18.10.201120:09:38DEBUG (TestTask.java:27) - Task10 : is completed.
18.10.201120:09:38DEBUG (TestTask.java:25) - Task11 : is started.
18.10.201120:09:38DEBUG (TestTask.java:27) - Task14 : is completed.
18.10.201120:09:38DEBUG (TestTask.java:27) - Task15 : is completed.
18.10.201120:09:38DEBUG (TestTask.java:25) - Task12 : is started.
18.10.201120:09:38DEBUG (TestTask.java:25) - Task13 : is started.
18.10.201120:09:38DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :3 - CompletedTaskCount :9 - TotalTaskCount :12 - isTerminated :false
18.10.201120:09:43DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :3 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :3 - CompletedTaskCount :9 - TotalTaskCount :12 - isTerminated :false
18.10.201120:09:48DEBUG (TestTask.java:27) - Task11 : is completed.
18.10.201120:09:48DEBUG (TestTask.java:27) - Task13 : is completed.
18.10.201120:09:48DEBUG (TestTask.java:27) - Task12 : is completed.
18.10.201120:09:48DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :0 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :0 - CompletedTaskCount :12 - TotalTaskCount :12 - isTerminated :true
18.10.201120:09:53DEBUG (ThreadPoolMonitorService.java:39) - CurrentPoolSize :0 - CorePoolSize :1 - MaximumPoolSize :3 - ActiveTaskCount :0 - CompletedTaskCount :12 - TotalTaskCount :12 - isTerminated :true

第15步:下载

  • OTV_Spring_ThreadPool
原文链接: dzone 翻译: ImportNew.com - 文 学敏
译文链接: http://www.importnew.com/14163.html
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 禁止进入待行区的时候进入了怎么办 今天开车把72岁老太婆撞了怎么办 在这种路口遇到行人突然横穿怎么办 在左拐车道却直行了怎么办 路边简易房让拆除不想拆怎么办 英国护照的名和姓印颠倒了怎么办 加热圈功率小加不到设定温度怎么办 本田飞度05年车尾气不好怎么办 文件在lr中打开后找不到了怎么办 手机安装软件成功屏幕上没有怎么办 脸过敏发红痒怎么办用什么药膏 脸上又红又肿又痒怎么办 宝宝把皮革咬烂吃掉了怎么办 自动档皮革挡把防尘套烂了怎么办 pu包用酒精擦坏了怎么办 白色的面料被84弄黄了怎么办 要账的人赖在家不走怎么办 两塔吊的安全距离不够2米怎么办 腿上被蚊子咬后留下的黑疤怎么办 携程订的酒店酒店一直没确认怎么办 客斤的无窗挨着厨房怎么办 餐桌和墙紧挨着容易脏怎么办 vivo手机被设置成英文该怎么办 电脑开机后显示英文字该怎么办? 看到文言文就不会翻译该怎么办呢 房间楼层太高闷热不通风怎么办 对方全责不理赔没有财产怎么办啊 买二手房过户后发现房顶漏水怎么办 钻石绣的钻两个粘在一起怎么办 开修理部的一天不干活都着急怎么办 调好的车漆时间长了有点稠怎么办 下滤鱼缸下水管声音大怎么办 家里水管不开水龙头就总是响怎么办 生完儿子后腹股沟特黑怎么办 因盗窃罪出狱数额较大还不起怎么办 司法拍卖房原房主拒绝搬离怎么办 wps卡了没反应没有保存怎么办 微信扫描支付环境有风险怎么办 手机安装东西突然要扫描很久怎么办 我惹朋友真的很生气了怎么办 买了保险后又犯杀人罪 保险怎么办