JAVA多线程

一个程序就是一个进程,而一个程序中的多个任务则被称为线程。

JAVA使用多线程

1.继承Thread类

2.实现Runnable接口

线程安全

synchronized关键字

实例变量

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
public class ThreadTest implements Runnable{
private int count = 100; // 成员变量

@Override
public void run() {
count --;
int i=100; // 局部变量
i = i-1;
System.out.println(Thread.currentThread().getName() + "---:" + count + ";i=" + i);
}

public static void main(String args[]) {
ThreadTest myThread = new ThreadTest();
Thread a = new Thread(myThread,"A");
Thread b = new Thread(myThread,"B");
Thread c = new Thread(myThread,"C");
Thread d = new Thread(myThread,"D");

a.start();
b.start();
c.start();
d.start();

System.out.println("--------------");

ThreadTest myThread2 = new ThreadTest();
Thread a1 = new Thread(myThread2,"A1");
Thread a2 = new Thread(myThread2,"A2");

a1.start();
a2.start();
}
}

运行结果:

1
2
3
4
5
6
7
--------------
D---:99;i=99
A2---:98;i=99
C---:98;i=99
A1---:98;i=99
B---:97;i=99
A---:96;i=99

a,b,c,d线程使用共享变量count。线程a1,b1与线程a,b,c,d不使用共享变量。可以使用synchronized关键字使各个线程排队执行run()方法synchronized public void run() {

同一个对象多个线程执行,共享成员变量,不共享局部变量
不同对象多个线程,不共享成员变量

结束线程的方法

  1. 使用标志位终止线程还可以线程中去数据库读取本任务的状态信息判断是否退出
    1
    2
    3
    4
    5
    6
    public volatile boolean exit = false;
    public void setExit(boolean exit) {
    this.exit = exit;
    }
    ...
    xxx.setExit(true); // 退出所有线程,还可以改造成根据条件判断退出指定线程
  2. interrupt()中断线程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class InterruptThreadTest extends Thread {
    public static void main(String[] args) {
    try {
    InterruptThreadTest t = new InterruptThreadTest();
    t.start();
    Thread.sleep(200);
    t.interrupt();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    @Override
    public void run() {
    for (int i = 0; i <= 100000; i++) {
    if (Thread.currentThread().isInterrupted()) {
    break;
    }
    System.out.println("i=" + i);
    }
    }
    }

Spring线程池配置

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
@Configuration
public class ThreadPoolConfig {
// 核心线程池大小
private int corePoolSize = 50;

// 最大可创建的线程数
private int maxPoolSize = 200;

// 队列最大长度
private int queueCapacity = 1000;

// 线程池维护线程所允许的空闲时间
private int keepAliveSeconds = 300;

@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setMaxPoolSize(maxPoolSize);
executor.setCorePoolSize(corePoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
// 线程池对拒绝任务(无线程可用)的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}

/**
* 执行周期性或定时任务
*/
@Bean(name = "scheduledExecutorService")
protected ScheduledExecutorService scheduledExecutorService() {
return new ScheduledThreadPoolExecutor(corePoolSize,
new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Threads.printException(r, t);
}
};
}
}

其他

线程调度 线程池性能?
创建、销毁线程需要消耗资源。
需要建线程任务,多线程就是为了并发。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ThreadPoolExample1 {

public static void main(String[] args) {

ExecutorService e = Executors.newCachedThreadPool();

for (int i = 0 ; i < 10 ; i++){
final int index = i;
e.execute(new Runnable() {
@Override
public void run() {
log.info("task:{}" ,index);
}
});
}
e.shutdown();
}
}

参考