diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..36bba055 Binary files /dev/null and b/.DS_Store differ diff --git a/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java b/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java index 5a00ab24..7967c29c 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/DaemonThread.java @@ -17,7 +17,8 @@ public void run() { }; Thread thread = new Thread(task); thread.setName("test-thread-1"); - thread.setDaemon(false); + // 设置为true时 主线程退出后上面的子线程只有一个会直接退出,不会打印当前线程...... + thread.setDaemon(true); thread.start(); } diff --git a/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java b/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java index d80e8c14..3a20deeb 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/Runner2.java @@ -15,7 +15,7 @@ public void run() { boolean result3 = Thread.currentThread().isInterrupted(); System.out.println("Runner2.run result ===>" + result); - System.out.println("Runner2.run result1 ===>" + result1); + System.out.println("Runner2.run result1 has reset===>" + result1); System.out.println("Runner2.run result3 ===>" + result3); diff --git a/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java b/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java index 626f2d38..290ae35b 100644 --- a/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java +++ b/03concurrency/0301/src/main/java/java0/conc0301/RunnerMain.java @@ -16,7 +16,8 @@ public static void main(String[] args) throws IOException { thread1.start(); thread2.start(); - thread2.interrupt(); // i = true + // i = true 注意与interrupted 的区别 + thread2.interrupt(); System.out.println(Thread.activeCount()); diff --git a/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java index aaf9567d..5b02350b 100644 --- a/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java @@ -19,7 +19,7 @@ public static void main(String[] args) { // // 串行,单线程 // longList.stream().forEach( // 并行,默认使用CPU * 2个线程 - longList.stream().forEach( + longList.stream().parallel().forEach( i -> { try { blockingQueue.put(i); diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/ExchangerDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/ExchangerDemo.java new file mode 100644 index 00000000..252630cd --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/ExchangerDemo.java @@ -0,0 +1,84 @@ +package java0.conc0303.tool; + +import java.util.concurrent.Exchanger; +import java.util.concurrent.TimeUnit; + +/** + * Exchanger 是 JDK 1.5 开始提供的一个用于两个工作线程之间交换数据的封装工具类, + * 简单说就是一个线程在完成一定的任务后想与另一个线程交换数据,则第一个先拿出数据的线程会一直等待第二个线程, + * 直到第二个线程拿着数据到来时才能彼此交换对应数据。 + * 其定义为 Exchanger 泛型类型,其中 V 表示可交换的数据类型,对外提供的接口很简单,具体如下: + * Exchanger():无参构造方法。 + *

+ * V exchange(V v):等待另一个线程到达此交换点(除非当前线程被中断),然后将给定的对象传送给该线程,并接收该线程的对象。 + *

+ * V exchange(V v, long timeout, TimeUnit unit):等待另一个线程到达此交换点(除非当前线程被中断或超出了指定的等待时间),然后将给定的对象传送给该线程,并接收该线程的对象。 + *

+ * 当一个线程到达 exchange 调用点时,如果其他线程此前已经调用了此方法, + * 则其他线程会被调度唤醒并与之进行对象交换,然后各自返回; + * 如果其他线程还没到达交换点,则当前线程会被挂起,直至其他线程到达才会完成交换并正常返回,或者当前线程被中断或超时返回。 + * + * @author jasper + */ +public class ExchangerDemo { + static class Producer extends Thread { + private Exchanger exchanger; + private static int data = 0; + + Producer(String name, Exchanger exchanger) { + super("Producer-" + name); + this.exchanger = exchanger; + } + + @Override + public void run() { + for (int i = 1; i < 5; i++) { + try { + TimeUnit.SECONDS.sleep(1); + data = i; + + System.out.println(getName() + i + " 交换前:" + data); + data = exchanger.exchange(data); + System.out.println(getName() + i + " 交换后:" + data); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + static class Consumer extends Thread { + private Exchanger exchanger; + private static int data = 0; + + Consumer(String name, Exchanger exchanger) { + super("Consumer-" + name); + this.exchanger = exchanger; + } + + @Override + public void run() { + int i = 1; + while (true) { + data = 0; + System.out.println(getName() + i + " 交换前:" + data); + try { + TimeUnit.SECONDS.sleep(1); + data = exchanger.exchange(data); + } catch (InterruptedException e) { + e.printStackTrace(); + } + System.out.println(getName() + i + " 交换后:" + data); + i++; + } + } + } + + public static void main(String[] args) throws InterruptedException { + Exchanger exchanger = new Exchanger<>(); + new Producer("", exchanger).start(); + new Consumer("", exchanger).start(); + TimeUnit.SECONDS.sleep(7); + System.exit(-1); + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/PhaserDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/PhaserDemo.java new file mode 100644 index 00000000..037a2fed --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/PhaserDemo.java @@ -0,0 +1,104 @@ +package java0.conc0303.tool; + +import java0.conc0303.tool.domain.StudentTask; + +import java.util.concurrent.Phaser; + +/*** + * 下面说说Phaser的高级用法,在Phaser内有2个重要状态,分别是phase和parties。 + * phase就是阶段,初值为0,当所有的线程执行完本轮任务,同时开始下一轮任务时, + * 意味着当前阶段已结束,进入到下一阶段,phase的值自动加1。 + * parties就是线程,party=4就意味着Phaser对象当前管理着4个线程。Phaser还有一个重要的方法经常需要被重载, + * 那就是boolean onAdvance(int phase, int registeredParties)方法。此方法有2个作用: + * 1、当每一个阶段执行完毕,此方法会被自动调用,因此,重载此方法写入的代码会在每个阶段执行完毕时执行, + * 相当于CyclicBarrier的barrierAction。 + * 2、当此方法返回true时,意味着Phaser被终止,因此可以巧妙的设置此方法的返回值来终止所有线程。 + * @author null + */ +public class PhaserDemo extends Phaser { + /** + * 在每个阶段执行完成后回调的方法 + * + * @param phase + * @param registeredParties + * @return + */ + @Override + protected boolean onAdvance(int phase, int registeredParties) { + + switch (phase) { + case 0: + return studentArrived(); + case 1: + return finishFirstExercise(); + case 2: + return finishSecondExercise(); + case 3: + return finishExam(); + default: + return true; + } + + } + + private boolean studentArrived() { + System.out.println("学生准备好了,学生人数:" + getRegisteredParties()); + return false; + } + + private boolean finishFirstExercise() { + System.out.println("第一题所有学生做完"); + return false; + } + + private boolean finishSecondExercise() { + System.out.println("第二题所有学生做完"); + return false; + } + + private boolean finishExam() { + System.out.println("第三题所有学生做完,结束考试"); + return true; + } + + /** + * 题目:5个学生参加考试,一共有三道题,要求所有学生到齐才能开始考试 + * ,全部做完第一题,才能继续做第二题,后面类似。 + *

+ * Phaser有phase和party两个重要状态, + * phase表示阶段,party表示每个阶段的线程个数, + * 只有每个线程都执行了phaser.arriveAndAwaitAdvance(); + * 才会进入下一个阶段,否则阻塞等待。 + * 例如题目中5个学生(线程)都调用phaser.arriveAndAwaitAdvance();就进入下一题 + * + * @author null + */ + public static void main(String[] args) { + PhaserDemo phaser = new PhaserDemo(); + StudentTask[] studentTask = new StudentTask[5]; + for (int i = 0; i < studentTask.length; i++) { + studentTask[i] = new StudentTask(phaser); + // 注册一次表示phaser维护的线程个数 + phaser.register(); + } + + Thread[] threads = new Thread[studentTask.length]; + for (int i = 0; i < studentTask.length; i++) { + threads[i] = new Thread(studentTask[i], "Student " + i); + threads[i].start(); + } + + // 等待所有线程执行结束 + for (int i = 0; i < studentTask.length; i++) { + try { + threads[i].join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + System.out.println("Phaser has finished:" + phaser.isTerminated()); + + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo.java index 542ae10b..50521af3 100644 --- a/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo.java @@ -9,6 +9,8 @@ public static void main(String[] args) { Semaphore semaphore = new Semaphore(1); //机器数目 for (int i = 0; i < N; i++) new Worker(i, semaphore).start(); + + System.out.println("主线程退出"); } static class Worker extends Thread { diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/domain/StudentTask.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/domain/StudentTask.java new file mode 100644 index 00000000..7ff2ff82 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/domain/StudentTask.java @@ -0,0 +1,65 @@ +package java0.conc0303.tool.domain; + +import java.util.concurrent.Phaser; +import java.util.concurrent.TimeUnit; + +/** + * @author jasper + */ +public class StudentTask implements Runnable { + + private Phaser phaser; + + public StudentTask(Phaser phaser) { + this.phaser = phaser; + } + + @Override + public void run() { + System.out.println(Thread.currentThread().getName() + "到达考试"); + phaser.arriveAndAwaitAdvance(); + + System.out.println(Thread.currentThread().getName() + "开始做第1题..."); + doExercise1(); + System.out.println(Thread.currentThread().getName() + "做第1题完成..."); + phaser.arriveAndAwaitAdvance(); + + System.out.println(Thread.currentThread().getName() + "开始做第2题..."); + doExercise2(); + System.out.println(Thread.currentThread().getName() + "做第2题完成..."); + phaser.arriveAndAwaitAdvance(); + + System.out.println(Thread.currentThread().getName() + "开始做第3题..."); + doExercise3(); + System.out.println(Thread.currentThread().getName() + "做第3题完成..."); + phaser.arriveAndAwaitAdvance(); + } + + private void doExercise1() { + long duration = (long) (Math.random() * 10); + try { + TimeUnit.SECONDS.sleep(duration); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void doExercise2() { + long duration = (long) (Math.random() * 10); + try { + TimeUnit.SECONDS.sleep(duration); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void doExercise3() { + long duration = (long) (Math.random() * 10); + try { + TimeUnit.SECONDS.sleep(duration); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/04fx/.DS_Store b/04fx/.DS_Store new file mode 100644 index 00000000..f1f975c8 Binary files /dev/null and b/04fx/.DS_Store differ diff --git a/04fx/spring01/src/main/java/io/kimmking/aop/ISchool.java b/04fx/spring01/src/main/java/io/kimmking/aop/ISchool.java index 3e9d8f1f..4731bd61 100644 --- a/04fx/spring01/src/main/java/io/kimmking/aop/ISchool.java +++ b/04fx/spring01/src/main/java/io/kimmking/aop/ISchool.java @@ -3,5 +3,6 @@ public interface ISchool { void ding(); + void dong(); } diff --git a/04fx/spring01/src/main/java/io/kimmking/spring01/GuavaDemo.java b/04fx/spring01/src/main/java/io/kimmking/spring01/GuavaDemo.java index 98ef1c51..7ddc9cef 100644 --- a/04fx/spring01/src/main/java/io/kimmking/spring01/GuavaDemo.java +++ b/04fx/spring01/src/main/java/io/kimmking/spring01/GuavaDemo.java @@ -61,7 +61,7 @@ public static void main(String[] args) throws IOException { a -> bMultimap.put(a,a+1) ); print(bMultimap); - + // 要求key value都唯一 BiMap words = HashBiMap.create(); words.put("First", 1); words.put("Second", 2); diff --git a/04fx/spring01/src/main/java/io/kimmking/spring01/LombokDemo.java b/04fx/spring01/src/main/java/io/kimmking/spring01/LombokDemo.java index 470db3b7..03c9c81e 100644 --- a/04fx/spring01/src/main/java/io/kimmking/spring01/LombokDemo.java +++ b/04fx/spring01/src/main/java/io/kimmking/spring01/LombokDemo.java @@ -14,7 +14,7 @@ public static void main(String[] args) throws IOException { Student student1 = new Student(); student1.setId(1); student1.setName("KK01"); - System.out.println(student1.toString()); + log.info(student1.toString()); Student student2 = new Student(2, "KK02"); System.out.println(student2.toString()); diff --git a/04fx/spring01/src/main/java/io/kimmking/spring02/Aop1.java b/04fx/spring01/src/main/java/io/kimmking/spring02/Aop1.java index 35447d56..e5d16e3f 100644 --- a/04fx/spring01/src/main/java/io/kimmking/spring02/Aop1.java +++ b/04fx/spring01/src/main/java/io/kimmking/spring02/Aop1.java @@ -1,26 +1,33 @@ package io.kimmking.spring02; +import io.kimmking.spring01.Student; +import lombok.Data; import org.aspectj.lang.ProceedingJoinPoint; +import javax.annotation.Resource; + +@Data public class Aop1 { - - //前置通知 - public void startTransaction(){ - System.out.println(" ====>begin ding... "); - } - - //后置通知 - public void commitTransaction(){ - System.out.println(" ====>finish ding... "); - } - - //环绕通知 - public void around(ProceedingJoinPoint joinPoint) throws Throwable{ - System.out.println(" ====>around begin ding"); - //调用process()方法才会真正的执行实际被代理的方法 - joinPoint.proceed(); - - System.out.println(" ====>around finish ding"); - } - + @Resource(name = "student100") + Student student100; + + //前置通知 + public void startTransaction() { + System.out.println(" ====>begin ding... "); + } + + //后置通知 + public void commitTransaction() { + System.out.println(" ====>finish ding... "); + } + + //环绕通知 + public void around(ProceedingJoinPoint joinPoint) throws Throwable { + System.out.println(" ====>around begin ding"); + //调用process()方法才会真正的执行实际被代理的方法 + joinPoint.proceed(); + + System.out.println(" ====>around finish ding"); + } + } diff --git a/04fx/spring01/src/main/java/io/kimmking/spring02/School.java b/04fx/spring01/src/main/java/io/kimmking/spring02/School.java index 7c700e64..d07a63da 100644 --- a/04fx/spring01/src/main/java/io/kimmking/spring02/School.java +++ b/04fx/spring01/src/main/java/io/kimmking/spring02/School.java @@ -23,5 +23,10 @@ public void ding(){ System.out.println("Class1 have " + this.class1.getStudents().size() + " students and one is " + this.student100); } - + + @Override + public void dong() { + System.out.println("call dong......"); + } + } diff --git a/04fx/spring01/src/main/java/io/kimmking/spring02/SpringDemo01.java b/04fx/spring01/src/main/java/io/kimmking/spring02/SpringDemo01.java index 8241be04..bde12a11 100644 --- a/04fx/spring01/src/main/java/io/kimmking/spring02/SpringDemo01.java +++ b/04fx/spring01/src/main/java/io/kimmking/spring02/SpringDemo01.java @@ -22,17 +22,18 @@ public static void main(String[] args) { System.out.println(class1); System.out.println("Klass对象AOP代理后的实际类型:"+class1.getClass()); System.out.println("Klass对象AOP代理后的实际类型是否是Klass子类:"+(class1 instanceof Klass)); - + + ISchool school = context.getBean(ISchool.class); System.out.println(school); System.out.println("ISchool接口的对象AOP代理后的实际类型:"+school.getClass()); - + ISchool school1 = context.getBean(ISchool.class); System.out.println(school1); System.out.println("ISchool接口的对象AOP代理后的实际类型:"+school1.getClass()); school1.ding(); - + school.dong(); class1.dong(); System.out.println(" context.getBeanDefinitionNames() ===>> "+ String.join(",", context.getBeanDefinitionNames())); diff --git a/04fx/spring01/src/main/resources/applicationContext.xml b/04fx/spring01/src/main/resources/applicationContext.xml index 681cf409..50799f74 100644 --- a/04fx/spring01/src/main/resources/applicationContext.xml +++ b/04fx/spring01/src/main/resources/applicationContext.xml @@ -43,11 +43,11 @@ - + - + diff --git a/04fx/spring01/src/main/resources/log4j.xml b/04fx/spring01/src/main/resources/log4j.xml index efc1f4f6..3555ba51 100644 --- a/04fx/spring01/src/main/resources/log4j.xml +++ b/04fx/spring01/src/main/resources/log4j.xml @@ -20,7 +20,7 @@ - + diff --git a/04fx/spring01/src/test/java/Spring02Test.java b/04fx/spring01/src/test/java/Spring02Test.java index 2cacae2e..84b604b4 100644 --- a/04fx/spring01/src/test/java/Spring02Test.java +++ b/04fx/spring01/src/test/java/Spring02Test.java @@ -4,15 +4,15 @@ import static org.mockito.Mockito.*; public class Spring02Test { - + private Klass class1; - + @Test public void KlassTest(){ class1 = mock(Klass.class, RETURNS_DEEP_STUBS); when(class1.getStudents().size()).thenReturn(2); Assert.assertEquals(2, class1.getStudents().size()); } - + // 单元测试 } diff --git a/04fx/spring01/src/test/java/Sprint01Test.java b/04fx/spring01/src/test/java/Sprint01Test.java index cbb69b90..9316a6ba 100644 --- a/04fx/spring01/src/test/java/Sprint01Test.java +++ b/04fx/spring01/src/test/java/Sprint01Test.java @@ -9,14 +9,14 @@ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:applicationContext.xml"}) public class Sprint01Test { - + @Autowired private Klass class1; - + @Test public void KlassTest(){ Assert.assertEquals(2, class1.getStudents().size()); } - + // 集成测试 } diff --git a/04fx/spring01/target/classes/applicationContext.xml b/04fx/spring01/target/classes/applicationContext.xml new file mode 100644 index 00000000..50799f74 --- /dev/null +++ b/04fx/spring01/target/classes/applicationContext.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04fx/spring01/target/classes/log4j.xml b/04fx/spring01/target/classes/log4j.xml new file mode 100644 index 00000000..3555ba51 --- /dev/null +++ b/04fx/spring01/target/classes/log4j.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04fx/spring01/target/classes/springjms-receiver.xml b/04fx/spring01/target/classes/springjms-receiver.xml new file mode 100644 index 00000000..e0d9fbc6 --- /dev/null +++ b/04fx/spring01/target/classes/springjms-receiver.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04fx/spring01/target/classes/springjms-sender.xml b/04fx/spring01/target/classes/springjms-sender.xml new file mode 100644 index 00000000..119ec07a --- /dev/null +++ b/04fx/spring01/target/classes/springjms-sender.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/04fx/springboot01/target/classes/application.yml b/04fx/springboot01/target/classes/application.yml new file mode 100644 index 00000000..f18263ac --- /dev/null +++ b/04fx/springboot01/target/classes/application.yml @@ -0,0 +1,53 @@ +server: + port: 8080 + +spring: + activemq: + broker-url: tcp://127.0.0.1:61616 + user: admin + password: admin + close-timeout: 15s # 在考虑结束之前等待的时间 + in-memory: true # 默认代理URL是否应该在内存中。如果指定了显式代理,则忽略此值。 + non-blocking-redelivery: false # 是否在回滚回滚消息之前停止消息传递。这意味着当启用此命令时,消息顺序不会被保留。 + send-timeout: 0 # 等待消息发送响应的时间。设置为0等待永远。 + queue-name: active.queue + topic-name: active.topic.name.model + packages: + trust-all: true #不配置此项,会报错 + pool: + enabled: true + max-connections: 10 #连接池最大连接数 + idle-timeout: 30000 #空闲的连接过期时间,默认为30秒 + data: + mongodb: + uri: mongodb://localhost:27017/mydb + +# jms: +# pub-sub-domain: true #默认情况下activemq提供的是queue模式,若要使用topic模式需要配置下面配置 + +# 是否信任所有包 +#spring.activemq.packages.trust-all= +# 要信任的特定包的逗号分隔列表(当不信任所有包时) +#spring.activemq.packages.trusted= +# 当连接请求和池满时是否阻塞。设置false会抛“JMSException异常”。 +#spring.activemq.pool.block-if-full=true +# 如果池仍然满,则在抛出异常前阻塞时间。 +#spring.activemq.pool.block-if-full-timeout=-1ms +# 是否在启动时创建连接。可以在启动时用于加热池。 +#spring.activemq.pool.create-connection-on-startup=true +# 是否用Pooledconnectionfactory代替普通的ConnectionFactory。 +#spring.activemq.pool.enabled=false +# 连接过期超时。 +#spring.activemq.pool.expiry-timeout=0ms +# 连接空闲超时 +#spring.activemq.pool.idle-timeout=30s +# 连接池最大连接数 +#spring.activemq.pool.max-connections=1 +# 每个连接的有效会话的最大数目。 +#spring.activemq.pool.maximum-active-session-per-connection=500 +# 当有"JMSException"时尝试重新连接 +#spring.activemq.pool.reconnect-on-exception=true +# 在空闲连接清除线程之间运行的时间。当为负数时,没有空闲连接驱逐线程运行。 +#spring.activemq.pool.time-between-expiration-check=-1ms +# 是否只使用一个MessageProducer +#spring.activemq.pool.use-anonymous-producers=true \ No newline at end of file