banner
NEWS LETTER

code

Scroll down

1. 多线程轮流打印

  • 使用synchronized + wait/notify,该方法存在唤醒多个线程进行无意义锁竞争的问题
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
public class MultipleThreadPrint {
private static final int CORE_SIZE = 5; //核心线程数
private static final int MAX_SIZE = 10; //最大线程数
private static final long KEEP_ALIVE_TIME = 1L; //非核心线程最大存活时间
private static final int QUEUE_SIZE = 10; //等待队列长度
private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(
CORE_SIZE,
MAX_SIZE,
KEEP_ALIVE_TIME,
TimeUnit.MINUTES,
new LinkedBlockingQueue<>(QUEUE_SIZE),
new ThreadPoolExecutor.CallerRunsPolicy()
);

private static int counter = 0;
static class Task implements Callable {
private final String NAME; //该任务的名字
private final int TARGET_NUM; //该任务需要打印的数字
private final int SUM_NUM; //需要打印的数字的总数
private final int PRINT_TIMES; //该任务需要打印的次数

public Task(String name, int targetNum, int sumNum, int printTimes) {
this.NAME = name;
this.TARGET_NUM = targetNum;
this.SUM_NUM = sumNum;
this.PRINT_TIMES = printTimes;
}

@Override
public Object call() {
for (int i = 0; i < PRINT_TIMES; i++) {
synchronized (MultipleThreadPrint.class) {
while (counter % SUM_NUM != TARGET_NUM) { //被唤醒的可能不是目标任务,需要再次检查
try {
MultipleThreadPrint.class.wait();
} catch (Exception e) {
e.printStackTrace();
}
}

System.out.println(NAME + ": " + counter);
counter++;
MultipleThreadPrint.class.notifyAll();
}
}

return null;
}
}

public static void main(String[] args) {
Task task1 = new Task("A", 0, 3, 10);
Task task2 = new Task("B", 1, 3, 10);
Task task3 = new Task("C", 2, 3, 10);

executor.submit(task1);
executor.submit(task2);
executor.submit(task3);
}
}
  • 使用Condition唤醒特定线程,从而避免无意义的锁竞争

2. 生产者消费者

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
public class ProducerConsumer {
private String message;
private boolean empty;

public synchronized void produce(String message) {
while(!empty) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}

this.message = message;
empty = false;
notifyAll();
}

public synchronized String consume() {
while (empty) {
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}

empty = true;
String message = this.message;
notifyAll();
return message;
}

public static void main(String[] args) {
ProducerConsumer pc = new ProducerConsumer();
Thread producer = new Thread(() -> {
pc.produce("message from producer");
});

Thread consumer = new Thread(() -> {
pc.consume();
});

producer.start();
consumer.start();
}
}

3. 懒汉双重校验单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package org.example.SimpleCode;

public class LazySingleton {
private static volatile LazySingleton instance; //volatile保证可见性

public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
if (instance == null) {
instance = new LazySingleton();
}
}
}

return instance;
}
}

instance必须由volatile修饰,防止出现以下情况双重校验单例模式异常情形

4. 反射操作

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
public class Main {
public static void main(String[] args) throws ClassNotFoundException,InstantiationException,IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
/*
获取TargetObject类的Class对象并且创建TargetObject类实例
*/
Class<?> targetClass = Class.forName("Reflection.TargetObject");
TargetObject targetObject = (TargetObject) targetClass.newInstance();

/*
获取指定参数并对参数进行修改
*/
Field field = targetClass.getDeclaredField("value");
//为了对类中的参数进行修改,取消安全检查
field.setAccessible(true);
field.set(targetObject,"3");
Field field1 = targetClass.getDeclaredField("age");
System.out.println(field1.getType() == int.class);

/*
获取TargetObject类中定义的所有办法
*/
Method[] methods = targetClass.getDeclaredMethods();
for(Method method : methods){
System.out.println(method.getName());
}

/*
获取指定方法并调用
*/
Method publicMethod = targetClass.getDeclaredMethod("publicMethod", String.class);
publicMethod.invoke(targetObject,"2");

/*
调用private方法
*/
Method privateMethod = targetClass.getDeclaredMethod("privateMethod");
//为了调用private方法,取消安全检查
privateMethod.setAccessible(true);
privateMethod.invoke(targetObject);
}
}

TargetObject.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class TargetObject {
private String value;

private int age;

public TargetObject(){
value = "1";
age = 1;
}
public void publicMethod(String str){
System.out.println("I love " + str);
}

private void privateMethod(){
System.out.println("value is " + value);
}
}

5. 控制台读取

1
2
3
4
5
6
Scanner sc = new Scanner(System.in);
while (sc.hasNextLine() || sc.hasNext()) {
System.out.println(sc.next());
System.out.println(sc.nextLine());
System.out.println(sc.nextInt());
}

6. 文件读取

1
2
3
4
5
6
7
8
try(BufferedReader br = new BufferedReader(new FileReader("input.txt"))) {
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}

7. 排序代码

8. 手撕HashMap

9. 手撕LRU

10. 实现定时任务

主要是通过Executors.newScheduledThreadPool实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ScheduledTask implements Runnable {

@Override
public void run() {
System.out.println("Thread:" + Thread.currentThread().getName());
}

public static void main(String[] args) {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
Runnable scheduledTask = new ScheduledTask();
//延迟0秒后执行,每隔一秒执行一次
executorService.scheduleAtFixedRate(scheduledTask, 0, 1, TimeUnit.SECONDS);
}
}
Other Articles
cover
  • 25/03/15
  • 13:32
cover
  • 25/02/18
  • 14:16