JAVA實(shí)現(xiàn)定時(shí)任務(wù)的幾種方式

JAVA實(shí)現(xiàn)定時(shí)任務(wù)的幾種方式

@(JAVA)[spring|quartz|定時(shí)器]
  近期項(xiàng)目開發(fā)中需要?jiǎng)討B(tài)的添加定時(shí)任務(wù)隅居,比如在某個(gè)活動(dòng)結(jié)束時(shí)钠至,自動(dòng)生成獲獎(jiǎng)名單,導(dǎo)出excel等胎源,此類任務(wù)由于活動(dòng)時(shí)間是動(dòng)態(tài)的棉钧,不能把定時(shí)任務(wù)配置在配置文件或?qū)懰涝诖a中。當(dāng)然也可以增加一個(gè)定時(shí)掃描的任務(wù)來實(shí)現(xiàn)涕蚤。借此機(jī)會(huì)整理了AVA實(shí)現(xiàn)定時(shí)任務(wù)的幾種常用方式宪卿,以下做簡要介紹。
目前主要有以下幾種實(shí)現(xiàn)方式:

  • JDK自帶 :JDK自帶的Timer以及JDK1.5+ 新增的ScheduledExecutorService万栅;
  • Quartz :簡單卻強(qiáng)大的JAVA作業(yè)調(diào)度框架
  • Spring3.0以后自帶的task :可以將它看成一個(gè)輕量級(jí)的Quartz佑钾,而且使用起來比Quartz簡單許多;
    下面將一一介紹以上三種實(shí)現(xiàn)方式烦粒。

[TOC]

JDK 自帶的定時(shí)器實(shí)現(xiàn)

  • Timer類
    這個(gè)類允許你調(diào)度一個(gè)java.util.TimerTask任務(wù)次绘。主要有以下幾個(gè)方法:
  1. schedule(TimerTask task, long delay) 延遲 delay 毫秒 執(zhí)行
public static void main(String[] args) {
        for (int i = 0; i < 10; ++i) {
            new Timer("timer - " + i).schedule(new TimerTask() {
                @Override
                public void run() {
                    println(Thread.currentThread().getName() + " run ");
                }
            }, 1000);
        }
    }
out :
timer - 2 run 
timer - 1 run 
timer - 0 run 
timer - 3 run 
timer - 9 run 
timer - 4 run 
timer - 8 run 
timer - 5 run 
timer - 6 run 
timer - 7 run 
  1. schedule(TimerTask task, Date time) 特定時(shí)間執(zhí)行
public static void main(String[] args) {
        for (int i = 0; i < 10; ++i) {
            new Timer("timer - " + i).schedule(new TimerTask() {
                @Override
                public void run() {
                    println(Thread.currentThread().getName() + " run ");
                }
            }, new Date(System.currentTimeMillis() + 2000));
        }
    }
out:
timer - 0 run 
timer - 7 run 
timer - 6 run 
timer - 8 run 
timer - 3 run 
timer - 5 run 
timer - 2 run 
timer - 1 run 
timer - 4 run 
timer - 9 run 
  1. schedule(TimerTask task, long delay, long period) 延遲 delay 執(zhí)行并每隔period 執(zhí)行一次
public static void main(String[] args) {
        for (int i = 0; i < 10; ++i) {
            new Timer("timer - " + i).schedule(new TimerTask() {
                @Override
                public void run() {
                    println(Thread.currentThread().getName() + " run ");
                }
            }, 2000 , 3000);
        }
    }
out:
timer - 0 run 
timer - 5 run 
timer - 4 run 
timer - 8 run 
timer - 3 run 
timer - 2 run 
timer - 1 run 
timer - 7 run 
timer - 9 run 
timer - 6 run 
timer - 3 run 
timer - 7 run 
timer - 5 run 
timer - 4 run 
timer - 8 run 
  • ScheduledExecutorService 接口實(shí)現(xiàn)類
    ScheduledExecutorService 是JAVA 1.5 后新增的定時(shí)任務(wù)接口,主要有以下幾個(gè)方法撒遣。
- ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit);
- <V> ScheduledFuture<V> schedule(Callable<V> callable,long delay, TimeUnit unit);
- ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnitunit);
- ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnitunit);

默認(rèn)實(shí)現(xiàn)為ScheduledThreadPoolExecutor 繼承了ThreadPoolExecutor 的線程池特性邮偎,配合future特性,比Timer更強(qiáng)大义黎。 具體用法可以閱讀JDK文檔禾进;spring Task內(nèi)部也是依靠它實(shí)現(xiàn)的。示例代碼:

public static void main(String[] args) throws SchedulerException {
        ScheduledThreadPoolExecutor executor = (ScheduledThreadPoolExecutor)Executors.newScheduledThreadPool(10);
        for (int i = 0; i < 10; ++i) {
            executor.schedule(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName() + " run ");
                }
            } , 2 , TimeUnit.SECONDS);
        }
        executor.shutdown();
    }

out:
pool-1-thread-2 run 
pool-1-thread-5 run 
pool-1-thread-4 run 
pool-1-thread-3 run 
pool-1-thread-8 run 
pool-1-thread-5 run 
pool-1-thread-7 run 
pool-1-thread-2 run 
pool-1-thread-1 run 
pool-1-thread-6 run 

Quartz 定時(shí)器實(shí)現(xiàn)

Quartz是一個(gè)完全由Java編寫的開源作業(yè)調(diào)度框架廉涕,為在Java應(yīng)用程序中進(jìn)行作業(yè)調(diào)度提供了簡單卻強(qiáng)大的機(jī)制泻云。Quartz允許開發(fā)人員根據(jù)時(shí)間間隔來調(diào)度作業(yè)艇拍。它實(shí)現(xiàn)了作業(yè)和觸發(fā)器的多對(duì)多的關(guān)系,還能把多個(gè)作業(yè)與不同的觸發(fā)器關(guān)聯(lián)宠纯。可以動(dòng)態(tài)的添加刪除定時(shí)任務(wù)卸夕,另外很好的支撐集群調(diào)度。簡單地創(chuàng)建一個(gè)org.quarz.Job接口的Java類婆瓜,Job接口包含唯一的方法:

public void execute(JobExecutionContext context) throws JobExecutionException;

在Job接口實(shí)現(xiàn)類里面快集,添加需要的邏輯到execute()方法中。配置好Job實(shí)現(xiàn)類并設(shè)定好調(diào)度時(shí)間表(Trigger)廉白,Quartz就會(huì)自動(dòng)在設(shè)定的時(shí)間調(diào)度作業(yè)執(zhí)行execute()个初。

整合了Quartz的應(yīng)用程序可以重用不同事件的作業(yè),還可以為一個(gè)事件組合多個(gè)作業(yè)猴蹂。Quartz通過屬性文件來配置JDBC事務(wù)的數(shù)據(jù)源院溺、全局作業(yè)、觸發(fā)器偵聽器磅轻、插件珍逸、線程池等等。(quartz.properties)

  1. 通過maven引入依賴(這里主要介紹2.3.0) 注意:shiro-scheduler中依賴的是1.x版本 如果同時(shí)使用會(huì)沖突
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>
  1. 創(chuàng)建Job類
public class TestJob implements Job{
    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        println(Thread.currentThread().getName() + " test job begin " + DateUtil.getCurrentTimeStr());
    }
}
  1. 調(diào)度任務(wù)
public static void main(String[] args) throws InterruptedException, SchedulerException {

        Scheduler scheduler = new StdSchedulerFactory().getScheduler();
        // 開始
        scheduler.start();
        // job 唯一標(biāo)識(shí) test.test-1
        JobKey jobKey = new JobKey("test" , "test-1");
        JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("test" , "test")
                // 延遲一秒執(zhí)行
                .startAt(new Date(System.currentTimeMillis() + 1000))
                // 每隔一秒執(zhí)行 并一直重復(fù)
        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
                .build();
        scheduler.scheduleJob(jobDetail , trigger);
        
        Thread.sleep(5000);
        // 刪除job
        scheduler.deleteJob(jobKey);
    }

out :
DefaultQuartzScheduler_Worker-1test job begin 2017-06-03 14:30:33
DefaultQuartzScheduler_Worker-2test job begin 2017-06-03 14:30:34
DefaultQuartzScheduler_Worker-3test job begin 2017-06-03 14:30:35
DefaultQuartzScheduler_Worker-4test job begin 2017-06-03 14:30:36
DefaultQuartzScheduler_Worker-5test job begin 2017-06-03 14:30:37

Quartz 主要包含以下幾個(gè)部分

Job:是一個(gè)接口聋溜,只有一個(gè)方法void execute(JobExecutionContext

context)弄息,開發(fā)者實(shí)現(xiàn)該接口定義運(yùn)行任務(wù),JobExecutionContext類提供了調(diào)度上下文的各種信息勤婚。Job運(yùn)行時(shí)的信息保存在JobDataMap實(shí)例中摹量;

JobDetail:Quartz在每次執(zhí)行Job時(shí),都重新創(chuàng)建一個(gè)Job實(shí)例馒胆,所以它不直接接受一個(gè)Job的實(shí)例缨称,相反它接收一個(gè)Job實(shí)現(xiàn)類,以便運(yùn)行時(shí)通過newInstance()的反射機(jī)制實(shí)例化Job祝迂。因此需要通過一個(gè)類來描述Job的實(shí)現(xiàn)類及其它相關(guān)的靜態(tài)信息睦尽,如Job名字、描述型雳、關(guān)聯(lián)監(jiān)聽器等信息当凡,JobDetail承擔(dān)了這一角色。

Trigger:是一個(gè)類纠俭,描述觸發(fā)Job執(zhí)行的時(shí)間觸發(fā)規(guī)則沿量。主要有SimpleTrigger和CronTrigger這兩個(gè)子類。當(dāng)僅需觸發(fā)一次或者以固定時(shí)間間隔周期執(zhí)行冤荆,SimpleTrigger是最適合的選擇朴则;而CronTrigger則可以通過Cron表達(dá)式定義出各種復(fù)雜時(shí)間規(guī)則的調(diào)度方案:如每早晨9:00執(zhí)行,周一钓简、周三乌妒、周五下午5:00執(zhí)行等汹想;

Calendar:org.quartz.Calendar和java.util.Calendar不同,它是一些日歷特定時(shí)間點(diǎn)的集合(可以簡單地將org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一個(gè)日歷時(shí)間點(diǎn)撤蚊,無特殊說明后面的Calendar即指org.quartz.Calendar)古掏。一個(gè)Trigger可以和多個(gè)Calendar關(guān)聯(lián),以便排除或包含某些時(shí)間點(diǎn)侦啸。假設(shè)槽唾,我們安排每周星期一早上10:00執(zhí)行任務(wù),但是如果碰到法定的節(jié)日匹中,任務(wù)則不執(zhí)行,這時(shí)就需要在Trigger觸發(fā)機(jī)制的基礎(chǔ)上使用Calendar進(jìn)行定點(diǎn)排除豪诲。

Scheduler:代表一個(gè)Quartz的獨(dú)立運(yùn)行容器顶捷,Trigger和JobDetail可以注冊(cè)到Scheduler中,兩者在Scheduler中擁有各自的組及名稱屎篱,組及名稱是Scheduler查找定位容器中某一對(duì)象的依據(jù)服赎,Trigger的組及名稱必須唯一,JobDetail的組和名稱也必須唯一(但可以和Trigger的組和名稱相同交播,因?yàn)樗鼈兪遣煌愋偷模┲芈恰cheduler定義了多個(gè)接口方法,允許外部通過組及名稱訪問和控制容器中Trigger和JobDetail秦士。

Scheduler可以將Trigger綁定到某一JobDetail中缺厉,這樣當(dāng)Trigger觸發(fā)時(shí),對(duì)應(yīng)的Job就被執(zhí)行隧土。一個(gè)Job可以對(duì)應(yīng)多個(gè)Trigger提针,但一個(gè)Trigger只能對(duì)應(yīng)一個(gè)Job〔芸可以通過SchedulerFactory創(chuàng)建一個(gè)Scheduler實(shí)例辐脖。Scheduler擁有一個(gè)SchedulerContext,它類似于ServletContext皆愉,保存著Scheduler上下文信息嗜价,Job和Trigger都可以訪問SchedulerContext內(nèi)的信息。SchedulerContext內(nèi)部通過一個(gè)Map幕庐,以鍵值對(duì)的方式維護(hù)這些上下文數(shù)據(jù)久锥,SchedulerContext為保存和獲取數(shù)據(jù)提供了多個(gè)put()和getXxx()的方法∫彀可以通過Scheduler#

getContext()獲取對(duì)應(yīng)的SchedulerContext實(shí)例奴拦;

ThreadPool:Scheduler使用一個(gè)線程池作為任務(wù)運(yùn)行的基礎(chǔ)設(shè)施,任務(wù)通過共享線程池中的線程提高運(yùn)行效率届吁。

關(guān)于簡單使用错妖,可以參考quartz的example绿鸣,下面鏈接是一些入門幫助。

Quartz定時(shí)任務(wù)學(xué)習(xí)(一)簡單任務(wù)
Quartz定時(shí)任務(wù)學(xué)習(xí)(二)web應(yīng)用
Quartz定時(shí)任務(wù)學(xué)習(xí)(三)屬性文件和jar

深入學(xué)習(xí)可以閱讀官方文檔和相關(guān)博客閱讀
以下為推薦博客地址
quartz詳解2:quartz由淺入深

Spring 相關(guān)的任務(wù)調(diào)度

  1. Spring 3.0+ 自帶的任務(wù)調(diào)度實(shí)現(xiàn)暂氯,主要依靠TaskScheduler接口的幾個(gè)實(shí)現(xiàn)類實(shí)現(xiàn)潮模。刪除和修改任務(wù)比較麻煩。
    主要用法有以下三種:
  • Spring配置文件實(shí)現(xiàn)
  • 注解實(shí)現(xiàn)
  • 代碼動(dòng)態(tài)添加

配置文件實(shí)現(xiàn)

spring-schedule.xml

<task:scheduler id="myScheduler" pool-size="10" />
<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="job" method="test" cron="0 * * * * ?"/>
</task:scheduled-tasks>

注解實(shí)現(xiàn)

spring-schedule.xml
<task:scheduler id="myScheduler" pool-size="10" />
// 啟用注解
<task:annotation-driven scheduler="myScheduler"/> 
@Component  
public class Task{  

       @Scheduled(cron="0/5 * *  * * ? ")   //每5秒執(zhí)行一次       
       public void execute(){     
             DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");    
             System.out.println(sdf.format(DateTime.now().toDate())+"*********B任務(wù)每5秒執(zhí)行一次進(jìn)入測(cè)試");      
       }      
}  

代碼動(dòng)態(tài)添加

spring-schedule.xml

<bean id = "myScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
        <property name="poolSize" value="10"/>
        <property name="threadGroupName" value="myScheduler" />
        <property name="threadNamePrefix" value="-1" />
</bean>
<task:annotation-driven scheduler="myScheduler"/> 
@Component
public class Test {
    
    @Autowired
    private ThreadPoolTaskScheduler myScheduler;
    
    public void addJob(){
        
        myScheduler.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + " run ");
            }
        } , new CronTrigger("0/5 * *  * * ? ")); //每5秒執(zhí)行一次
    }
}
  1. spring 結(jié)合 quartz 實(shí)現(xiàn)任務(wù)調(diào)度
  • spring 配置文件 spring-quartz.xml
<bean id="quartzsScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="false">
        <property name="triggers">
            <list>
            <ref bean="testTrigger" />
            </list>
        </property>
</bean>

<!-- jobClass需要繼承QuartzJobBean  也可以使用 MethodInvokingJobDetailFactoryBean 定義任意類任意方法為Job-->
<bean id="testJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
              <property name="jobClass">
                     <value>com.test.TestJob</value>
              </property>
              <property name="durability" value="true" />
              <!-- requestsRecovery屬性必須設(shè)置為 true痴施,當(dāng)Quartz服務(wù)被中止后擎厢,再次啟動(dòng)或集群中其他機(jī)器接手任務(wù)時(shí)會(huì)嘗試恢復(fù)執(zhí)行之前未完成的所有任務(wù) -->
              <property name="requestsRecovery" value="true" />
</bean>
<bean id="testTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
              <property name="jobDetail" ref="testJobDetail" />
              <property name="cronExpression" value="0 0 10 * * ?" />
</bean>

動(dòng)態(tài)增加刪除

@Component
public class Test {
    
    @Autowired
    private SchedulerFactoryBean quartzScheduler;
    
    public void addJob() throws SchedulerException {
        
        Scheduler scheduler = quartzScheduler.getScheduler();
        JobKey jobKey = new JobKey("test", "test");
        if (scheduler.checkExists(jobKey)) {
            return;
        }
        JobDetail jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).build();
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("test", "test")
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever()).build();
        scheduler.scheduleJob(jobDetail, trigger);
    }
}

以上僅僅是對(duì)自己學(xué)習(xí)的總結(jié),深入了解還需查找相關(guān)資料辣吃。比如動(dòng)態(tài)增加动遭,修改定時(shí)任務(wù)。以及Quartz的集群模式等神得。

配圖
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末厘惦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哩簿,更是在濱河造成了極大的恐慌宵蕉,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件节榜,死亡現(xiàn)場離奇詭異羡玛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宗苍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門稼稿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人讳窟,你說我怎么就攤上這事渺杉。” “怎么了挪钓?”我有些...
    開封第一講書人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵是越,是天一觀的道長。 經(jīng)常有香客問我碌上,道長倚评,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任馏予,我火速辦了婚禮天梧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘霞丧。我一直安慰自己呢岗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著后豫,像睡著了一般悉尾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上挫酿,一...
    開封第一講書人閱讀 49,079評(píng)論 1 285
  • 那天构眯,我揣著相機(jī)與錄音,去河邊找鬼早龟。 笑死惫霸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的葱弟。 我是一名探鬼主播壹店,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼芝加!你這毒婦竟也來了硅卢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤妖混,失蹤者是張志新(化名)和其女友劉穎老赤,沒想到半個(gè)月后轮洋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體制市,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年弊予,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了祥楣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡汉柒,死狀恐怖误褪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碾褂,我是刑警寧澤兽间,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站正塌,受9級(jí)特大地震影響嘀略,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乓诽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一帜羊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸠天,春花似錦讼育、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饥瓷。三九已至,卻和暖如春忧饭,著一層夾襖步出監(jiān)牢的瞬間扛伍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來泰國打工词裤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刺洒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓吼砂,卻偏偏與公主長得像逆航,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子渔肩,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • scheduler定時(shí)調(diào)度系統(tǒng)是大多行業(yè)項(xiàng)目都需要的因俐,傳統(tǒng)的spring-job模式,個(gè)人感覺已經(jīng)out了周偎,因?yàn)榇?..
    安琪拉_4b7e閱讀 2,825評(píng)論 4 6
  • 博客原文 徒手翻譯spring framework 4.2.3官方文檔的第33章抹剩,若有翻譯不當(dāng)之處請(qǐng)指正。 定時(shí)任...
    rabbitGYK閱讀 5,618評(píng)論 4 24
  • 我已擁有一次來自銷售課程分享的邀約蓉坎。在VUCA時(shí)代背景下澳眷,我們的銷售環(huán)境發(fā)生了哪些變化呢?銷售也正處在這樣的關(guān)鍵時(shí)...
    蔣萍coach閱讀 155評(píng)論 0 0
  • 在黑夜里夢(mèng)想著光 心中覆蓋悲傷 在悲傷里忍受孤獨(dú) 空守一絲溫暖 我的淚水是無底深海 對(duì)你的愛已無言 相信無盡的力量...
    熊睿兒閱讀 549評(píng)論 0 0
  • 十年前的我:你好 當(dāng)你收到這封信的時(shí)候蛉艾,你還在馬不停蹄的為你的兒女钳踊、為你的家不斷的勞累奔波嗎? 是不是女兒正在上大...
    川巒之旅閱讀 609評(píng)論 0 0