検索
ホームページJava&#&チュートリアルJava はスケジュールされたタスクを実装します。

1. Java スケジュールされたタスクは java.util.Timer を使用して実装できます

import java.util.Calendar;  
import java.util.Date;  
import java.util.Timer;  
import java.util.TimerTask;  
  
public class Test {  
    public static void main(String[] args) {  
        //timer1();  
        timer2();  
        //timer3();  
        //timer4();  
    }  
  
    // 第一种方法:设定指定任务task在指定时间time执行 schedule(TimerTask task, Date time)  
    public static void timer1() {  
        Timer timer = new Timer();  
        timer.schedule(new TimerTask() {  
            public void run() {  
                System.out.println("-------设定要指定任务--------");  
            }  
        }, 2000);// 设定指定的时间time,此处为2000毫秒  
    }  
  
    // 第二种方法:设定指定任务task在指定延迟delay后进行固定延迟peroid的执行  
    // schedule(TimerTask task, long delay, long period)  
    public static void timer2() {  
        Timer timer = new Timer();  
        timer.schedule(new TimerTask() {  
            public void run() {  
                System.out.println("-------设定要指定任务--------");  
            }  
        }, 1000, 1000);  
    }  
  
    // 第三种方法:设定指定任务task在指定延迟delay后进行固定频率peroid的执行。  
    // scheduleAtFixedRate(TimerTask task, long delay, long period)  
    public static void timer3() {  
        Timer timer = new Timer();  
        timer.scheduleAtFixedRate(new TimerTask() {  
            public void run() {  
                System.out.println("-------设定要指定任务--------");  
            }  
        }, 1000, 2000);  
    }  
     
    // 第四种方法:安排指定的任务task在指定的时间firstTime开始进行重复的固定速率period执行.  
    // Timer.scheduleAtFixedRate(TimerTask task,Date firstTime,long period)  
    public static void timer4() {  
        Calendar calendar = Calendar.getInstance();  
        calendar.set(Calendar.HOUR_OF_DAY, 12); // 控制时  
        calendar.set(Calendar.MINUTE, 0);       // 控制分  
        calendar.set(Calendar.SECOND, 0);       // 控制秒  
  
        Date time = calendar.getTime();         // 得出执行任务的时间,此处为今天的12:00:00  
  
        Timer timer = new Timer();  
        timer.scheduleAtFixedRate(new TimerTask() {  
            public void run() {  
                System.out.println("-------设定要指定任务--------");  
            }  
        }, time, 1000 * 60 * 60 * 24);// 这里设定将延时每天固定执行  
    }  
}

2. Java スケジュールされたタスクはスレッド待機によって実装できます

/**  
 * 普通thread  
 * 这是最常见的,创建一个thread,然后让它在while循环里一直运行着,  
 * 通过sleep方法来达到定时任务的效果。这样可以快速简单的实现,代码如下:  
 * @author GT  
 *  
 */    
public class Task1 {    
    public static void main(String[] args) {    
        // run in a second    
        final long timeInterval = 1000;    
        Runnable runnable = new Runnable() {    
            public void run() {    
                while (true) {    
                    // ------- code for task to run    
                    System.out.println("Hello !!");    
                    // ------- ends here    
                    try {    
                        Thread.sleep(timeInterval);    
                    } catch (InterruptedException e) {    
                        e.printStackTrace();    
                    }    
                }    
            }    
        };    
        Thread thread = new Thread(runnable);    
        thread.start();    
    }    
}

3. Java は java.util.concurrent.ScheduledExecutorService を使用して実装できます

import java.util.concurrent.Executors;    
import java.util.concurrent.ScheduledExecutorService;    
import java.util.concurrent.TimeUnit;    
    
/**  
 *   
 *   
 * ScheduledExecutorService是从Java SE5的java.util.concurrent里,做为并发工具类被引进的,这是最理想的定时任务实现方式。   
 * 相比于上两个方法,它有以下好处:  
 * 1>相比于Timer的单线程,它是通过线程池的方式来执行任务的   
 * 2>可以很灵活的去设定第一次执行任务delay时间  
 * 3>提供了良好的约定,以便设定执行的时间间隔  
 *   
 * 下面是实现代码,我们通过ScheduledExecutorService#scheduleAtFixedRate展示这个例子,通过代码里参数的控制,首次执行加了delay时间。  
 *   
 *   
 * @author GT  
 *   
 */    
public class Task3 {    
    public static void main(String[] args) {    
        Runnable runnable = new Runnable() {    
            public void run() {    
                // task to run goes here    
                System.out.println("Hello !!");    
            }    
        };    
        ScheduledExecutorService service = Executors    
                .newSingleThreadScheduledExecutor();    
        // 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间    
        service.scheduleAtFixedRate(runnable, 10, 1, TimeUnit.SECONDS);    
    }    
}

4. スケジュールされたタスク - Quartz の使用

Quartz は、ジョブ スケジューリングの分野における OpenSymphony オープン ソース組織のもう 1 つのオープン ソース プロジェクトであり、J2EE および J2SE アプリケーションと組み合わせたり、単独で使用したりできます。 Quartz を使用すると、10、数百、さらには数万のジョブを実行するための単純または複雑な毎日のスケジュールを作成できます。ジョブは、標準の Java コンポーネントまたは EJB に作成できます。



CronTrigger設定形式:
形式: [秒] [分] [時] [日] [月] [週] [年]

シリアル番号 説明 必須ですか?ワイルドカード

1 秒は 0-59 、 - * /

2 分は 0-59 、 - * /

3 時間は 0-23 、 - * /

4 日は 1-31 、 - * / ? L W

5 月 はい 1-12 または 1 月-12 月 、 - * /

6 週 はい 1-7 または SUN-SAT 、 - * / L #

7 年 いいえ 空または 1970-2099 、 - * /

ワイルドカードの説明:
* はすべての値を表します。例: 分フィールドに「*」を設定すると、毎分トリガーされることを意味します。
? 値が指定されていないことを意味します。使用シナリオでは、このフィールドの現在の値を気にする必要はありません。たとえば、毎月 10 日に操作をトリガーしたいが、曜日は関係ないため、曜日の位置を「?」に設定する必要があります。具体的には 0 0 に設定します。 0 10* ?
- 間隔を表します。たとえば、正時に「10-12」を設定すると、10 時、11 時、12 時にトリガーされることになります。
は、複数の値を指定することを意味します。たとえば、週フィールドに「MON,WED,FRI」を設定すると、月曜日、水曜日、金曜日にトリガーされることを意味します。
/ は、増分トリガーに使用されます。たとえば、秒より上の「5/15」を設定すると、5 秒から開始して 15 秒ごと (5、20、35、50) にトリガーされることを意味します。毎月 1 日に開始し、3 日ごとにトリガーするには、月フィールドに「1/3」を設定します。
Lは最後の言葉を意味します。日フィールドの設定では月の最終日を表し(現在の月に応じて、2 月の場合は閏年かどうかにも依存します)、週フィールドでは土曜日を表します。 「7」または「SAT」に相当します。 「L」の前に数字を付けると、最後のデータを意味します。たとえば、週フィールドに「6L」のような形式を設定すると、「今月の最後の金曜日」を意味します。
W は、指定した日付に最も近い営業日 (月曜日から金曜日) を意味します。たとえば、その日に「15W」を設定すると、その日を意味します。フィールド、毎月 15 日に最も近い営業日がトリガーされることを示します。 15 日が土曜日の場合、トリガーは最も近い金曜日 (14 日) に検出されます。15 日が週末の場合、トリガーは最も近い月曜日 (16 日) に検出されます。営業日 (月曜日から日曜日) 5)、その日にトリガーされます。指定された形式が「1W」の場合、毎月 1 日以降の最も近い営業日にトリガーされることを意味します。 1 日が土曜日の場合は、3 日の月曜日にトリガーされます。 (「W」の前には特定の数字のみを設定でき、「-」の間隔は許可されないことに注意してください。)

ヒント

「L」と「W」は組み合わせて使用​​できます。日フィールドに「LW」が設定されている場合、その月の最終営業日 (通常は給与支払いを指します) にトリガーされることを意味します

# シリアル番号 (それぞれの曜日を示します)フィールドに「6#3」を設定すると、各月の第 3 土曜日を示します。「#5」が指定され、第 5 週に土曜日がない場合、この構成は適用されないことに注意してください。トリガーされます (母の日と父の日に使用されます)。

ヒント 英語の文字が使用されている場合、週フィールドの設定は


です。

一般的な例:

0 0 12 * * ? 毎日 12 時にトリガーされます

0 15 10 ? 毎日 10:15 にトリガーされます

0 15 10 * * ?

0 15 10 * * ? 2005 年の毎日 10:15 にトリガーされました

0 * 14 * * ?    每天下午的 2点到2点59分每分触发    

0 0/5 14 * * ?    每天下午的 2点到2点59分(整点开始,每隔5分触发)    

0 0/5 14,18 * * ?    每天下午的 2点到2点59分(整点开始,每隔5分触发)每天下午的 18点到18点59分(整点开始,每隔5分触发)    

0 0-5 14 * * ?    每天下午的 2点到2点05分每分触发    

0 10,44 14 ? 3 WED    3月分每周三下午的 2点10分和2点44分触发    

0 15 10 ? * MON-FRI    从周一到周五每天上午的10点15分触发    

0 15 10 15 * ?    每月15号上午10点15分触发    

0 15 10 L * ?    每月最后一天的10点15分触发    

0 15 10 ? * 6L    每月最后一周的星期五的10点15分触发    

0 15 10 ? * 6L 2002-2005    从2002年到2005年每月最后一周的星期五的10点15分触发    

0 15 10 ? * 6#3    每月的第三周的星期五开始触发    

0 0 12 1/5 * ?    每月的第一个中午开始每隔5天触发一次    

0 11 11 11 11 ?    每年的11月11号 11点11分触发(光棍节)    

经过封装的管理类:

import java.text.ParseException;    
    
import org.quartz.CronTrigger;    
import org.quartz.JobDetail;    
import org.quartz.Scheduler;    
import org.quartz.SchedulerException;    
import org.quartz.SchedulerFactory;    
import org.quartz.impl.StdSchedulerFactory;    
    
/**  
 * 定时任务管理类  
 *  
 */    
public class QuartzManager {    
    private static SchedulerFactory gSchedulerFactory = new StdSchedulerFactory();    
    private static String JOB_GROUP_NAME = "EXTJWEB_JOBGROUP_NAME";    
    private static String TRIGGER_GROUP_NAME = "EXTJWEB_TRIGGERGROUP_NAME";    
    
    /**  
     * 添加一个定时任务,使用默认的任务组名,触发器名,触发器组名  
     *  
     * @param jobName  
     *            任务名  
     * @param jobClass  
     *            任务  
     * @param time  
     *            时间设置,参考quartz说明文档  
     * @throws SchedulerException  
     * @throws ParseException  
     */    
    public static void addJob(String jobName, String jobClass, String time) {    
        try {    
            Scheduler sched = gSchedulerFactory.getScheduler();    
            JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME, Class.forName(jobClass));// 任务名,任务组,任务执行类    
            // 触发器    
            CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组    
            trigger.setCronExpression(time);// 触发器时间设定    
            sched.scheduleJob(jobDetail, trigger);    
            // 启动    
            if (!sched.isShutdown()){    
                sched.start();    
            }    
        } catch (Exception e) {    
            e.printStackTrace();    
            throw new RuntimeException(e);    
        }    
    }    
    
    /**  
     * 添加一个定时任务  
     *  
     * @param jobName  
     *            任务名  
     * @param jobGroupName  
     *            任务组名  
     * @param triggerName  
     *            触发器名  
     * @param triggerGroupName  
     *            触发器组名  
     * @param jobClass  
     *            任务  
     * @param time  
     *            时间设置,参考quartz说明文档  
     * @throws SchedulerException  
     * @throws ParseException  
     */    
    public static void addJob(String jobName, String jobGroupName,    
            String triggerName, String triggerGroupName, String jobClass, String time){    
        try {    
            Scheduler sched = gSchedulerFactory.getScheduler();    
            JobDetail jobDetail = new JobDetail(jobName, jobGroupName, Class.forName(jobClass));// 任务名,任务组,任务执行类    
            // 触发器    
            CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组    
            trigger.setCronExpression(time);// 触发器时间设定    
            sched.scheduleJob(jobDetail, trigger);    
        } catch (Exception e) {    
            e.printStackTrace();    
            throw new RuntimeException(e);    
        }    
    }    
    
    /**  
     * 修改一个任务的触发时间(使用默认的任务组名,触发器名,触发器组名)  
     *  
     * @param jobName  
     * @param time  
     */    
    public static void modifyJobTime(String jobName, String time) {    
        try {    
            Scheduler sched = gSchedulerFactory.getScheduler();    
            CronTrigger trigger = (CronTrigger) sched.getTrigger(jobName, TRIGGER_GROUP_NAME);    
            if(trigger == null) {    
                return;    
            }    
            String oldTime = trigger.getCronExpression();    
            if (!oldTime.equalsIgnoreCase(time)) {    
                JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);    
                Class objJobClass = jobDetail.getJobClass();    
                String jobClass = objJobClass.getName();    
                removeJob(jobName);    
    
                addJob(jobName, jobClass, time);    
            }    
        } catch (Exception e) {    
            e.printStackTrace();    
            throw new RuntimeException(e);    
        }    
    }    
    
    /**  
     * 修改一个任务的触发时间  
     *  
     * @param triggerName  
     * @param triggerGroupName  
     * @param time  
     */    
    public static void modifyJobTime(String triggerName,    
            String triggerGroupName, String time) {    
        try {    
            Scheduler sched = gSchedulerFactory.getScheduler();    
            CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerName, triggerGroupName);    
            if(trigger == null) {    
                return;    
            }    
            String oldTime = trigger.getCronExpression();    
            if (!oldTime.equalsIgnoreCase(time)) {    
                CronTrigger ct = (CronTrigger) trigger;    
                // 修改时间    
                ct.setCronExpression(time);    
                // 重启触发器    
                sched.resumeTrigger(triggerName, triggerGroupName);    
            }    
        } catch (Exception e) {    
            e.printStackTrace();    
            throw new RuntimeException(e);    
        }    
    }    
    
    /**  
     * 移除一个任务(使用默认的任务组名,触发器名,触发器组名)  
     *  
     * @param jobName  
     */    
    public static void removeJob(String jobName) {    
        try {    
            Scheduler sched = gSchedulerFactory.getScheduler();    
            sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器    
            sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器    
            sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务    
        } catch (Exception e) {    
            e.printStackTrace();    
            throw new RuntimeException(e);    
        }    
    }    
    
    /**  
     * 移除一个任务  
     *  
     * @param jobName  
     * @param jobGroupName  
     * @param triggerName  
     * @param triggerGroupName  
     */    
    public static void removeJob(String jobName, String jobGroupName,    
            String triggerName, String triggerGroupName) {    
        try {    
            Scheduler sched = gSchedulerFactory.getScheduler();    
            sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器    
            sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器    
            sched.deleteJob(jobName, jobGroupName);// 删除任务    
        } catch (Exception e) {    
            e.printStackTrace();    
            throw new RuntimeException(e);    
        }    
    }    
    
    /**  
     * 启动所有定时任务  
     */    
    public static void startJobs() {    
        try {    
            Scheduler sched = gSchedulerFactory.getScheduler();    
            sched.start();    
        } catch (Exception e) {    
            e.printStackTrace();    
            throw new RuntimeException(e);    
        }    
    }    
    
    /**  
     * 关闭所有定时任务  
     */    
    public static void shutdownJobs() {    
        try {    
            Scheduler sched = gSchedulerFactory.getScheduler();    
            if(!sched.isShutdown()) {    
                sched.shutdown();    
            }    
        } catch (Exception e) {    
            e.printStackTrace();    
            throw new RuntimeException(e);    
        }    
    }    
}

简单实现Schedule的Quartz的例子


 第一步:引包

  要使用Quartz,必须要引入以下这几个包:

  1、log4j-1.2.16

  2、quartz-2.1.7

  3、slf4j-api-1.6.1.jar

  4、slf4j-log4j12-1.6.1.jar

  这些包都在下载的Quartz包里面包含着,因此没有必要为寻找这几个包而头疼。

  第二步:创建要被定执行的任务类

  这一步也很简单,只需要创建一个实现了org.quartz.Job接口的类,并实现这个接口的唯一一个方法execute(JobExecutionContext arg0) throws JobExecutionException即可。如:

import java.text.SimpleDateFormat;   
   
import java.util.Date;   
   
import org.quartz.Job;   
import org.quartz.JobExecutionContext;   
import org.quartz.JobExecutionException;   
   
public class myJob implements Job {   
   
    @Override   
    public void execute(JobExecutionContext arg0) throws JobExecutionException {   
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");   
        System.out.println(sdf.format(new Date()));   
    }   
   
}

第三步:创建任务调度,并执行

import java.text.SimpleDateFormat;  
import java.util.Date;  
  
import org.quartz.CronTrigger;  
import org.quartz.JobDetail;  
import org.quartz.Scheduler;  
import org.quartz.SchedulerFactory;  
import org.quartz.impl.StdSchedulerFactory;  
  
public class Test {  
    public void go() throws Exception {  
        // 首先,必需要取得一个Scheduler的引用  
        SchedulerFactory sf = new StdSchedulerFactory();  
        Scheduler sched = sf.getScheduler();  
        String time="0 51 11 ? * *";  
        // jobs可以在scheduled的sched.start()方法前被调用  
  
        // job 1将每隔20秒执行一次  
        JobDetail job = new JobDetail("job1", "group1", myJob.class);  
        CronTrigger trigger = new CronTrigger("trigger1", "group1");  
        trigger.setCronExpression(time);  
        Date ft = sched.scheduleJob(job, trigger);  
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");  
        System.out.println(  
                job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: " + trigger.getCronExpression());  
  
        // job 2将每2分钟执行一次(在该分钟的第15秒)  
        job = new JobDetail("job2", "group1",myJob.class);  
        trigger = new CronTrigger("trigger2", "group1");  
        trigger.setCronExpression(time);  
        ft = sched.scheduleJob(job, trigger);  
        System.out.println(  
                job.getKey() + " 已被安排执行于: " + sdf.format(ft) + ",并且以如下重复规则重复执行: " + trigger.getCronExpression());  
  
        // 开始执行,start()方法被调用后,计时器就开始工作,计时调度中允许放入N个Job  
        sched.start();  
        try {  
            // 主线程等待一分钟  
            Thread.sleep(60L * 1000L);  
        } catch (Exception e) {  
        }  
        // 关闭定时调度,定时器不再工作  
        sched.shutdown(true);  
    }  
  
    public static void main(String[] args) throws Exception {  
  
        Test test = new Test();  
        test.go();  
    }  
  
}



更多 java实现定时任务 Schedule相关文章请关注PHP中文网!


声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?カフェインやグアバキャッシュなどのライブラリを使用して、Javaアプリケーションにマルチレベルキャッシュを実装するにはどうすればよいですか?Mar 17, 2025 pm 05:44 PM

この記事では、カフェインとグアバキャッシュを使用してJavaでマルチレベルキャッシュを実装してアプリケーションのパフォーマンスを向上させています。セットアップ、統合、パフォーマンスの利点をカバーし、構成と立ち退きポリシー管理Best Pra

Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Javaのクラスロードメカニズムは、さまざまなクラスローダーやその委任モデルを含むどのように機能しますか?Mar 17, 2025 pm 05:35 PM

Javaのクラスロードには、ブートストラップ、拡張機能、およびアプリケーションクラスローダーを備えた階層システムを使用して、クラスの読み込み、リンク、および初期化が含まれます。親の委任モデルは、コアクラスが最初にロードされ、カスタムクラスのLOAに影響を与えることを保証します

Javaで機能的なプログラミング技術を実装するにはどうすればよいですか?Javaで機能的なプログラミング技術を実装するにはどうすればよいですか?Mar 11, 2025 pm 05:51 PM

この記事では、Lambda式、Streams API、メソッド参照、およびオプションを使用して、機能プログラミングをJavaに統合することを調べます。 それは、簡潔さと不変性を通じてコードの読みやすさと保守性の改善などの利点を強調しています

キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPA(Java Persistence API)を使用するにはどうすればよいですか?Mar 17, 2025 pm 05:43 PM

この記事では、キャッシュや怠zyなロードなどの高度な機能を備えたオブジェクトリレーショナルマッピングにJPAを使用することについて説明します。潜在的な落とし穴を強調しながら、パフォーマンスを最適化するためのセットアップ、エンティティマッピング、およびベストプラクティスをカバーしています。[159文字]

高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?高度なJavaプロジェクト管理、自動化の構築、依存関係の解像度にMavenまたはGradleを使用するにはどうすればよいですか?Mar 17, 2025 pm 05:46 PM

この記事では、Javaプロジェクト管理、自動化の構築、依存関係の解像度にMavenとGradleを使用して、アプローチと最適化戦略を比較して説明します。

非ブロッキングI/OにJavaのNIO(新しい入出力)APIを使用するにはどうすればよいですか?非ブロッキングI/OにJavaのNIO(新しい入出力)APIを使用するにはどうすればよいですか?Mar 11, 2025 pm 05:51 PM

この記事では、単一のスレッドで複数の接続を効率的に処理するためにセレクターとチャネルを使用して、非ブロッキングI/O用のJavaのNIO APIについて説明します。 プロセス、利点(スケーラビリティ、パフォーマンス)、および潜在的な落とし穴(複雑さ、

適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?適切なバージョン化と依存関係管理を備えたカスタムJavaライブラリ(JARファイル)を作成および使用するにはどうすればよいですか?Mar 17, 2025 pm 05:45 PM

この記事では、MavenやGradleなどのツールを使用して、適切なバージョン化と依存関係管理を使用して、カスタムJavaライブラリ(JARファイル)の作成と使用について説明します。

ネットワーク通信にJavaのソケットAPIを使用するにはどうすればよいですか?ネットワーク通信にJavaのソケットAPIを使用するにはどうすればよいですか?Mar 11, 2025 pm 05:53 PM

この記事では、ネットワーク通信のためのJavaのソケットAPI、クライアントサーバーのセットアップ、データ処理、リソース管理、エラー処理、セキュリティなどの重要な考慮事項をカバーしています。 また、パフォーマンスの最適化手法も調査します

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません