Java基础(十) -- 线程

实现方式

继承Thread类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Method1 {
public static void main(String[] args) {
A a = new A();
a.start();
System.out.println("主线程输出"+Thread.currentThread().getName());
}
}

class A extends Thread{
@Override
public void run() {

int i = 0;
while (i < 10){
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("子线程输出--"+Thread.currentThread().getName());
}
}
}

实现 Runnable 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Method2 {
public static void main(String[] args) {
A a = new A();
Thread thread = new Thread(a);
thread.start();
}
}

class A implements Runnable{

@Override
public void run() {
int i = 0;
while (i < 10){
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("子线程输出--"+Thread.currentThread().getName());
}
}
}

调试线程的工具

jconsole

通知线程退出

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
public class Method2 {
public static void main(String[] args) {
A a = new A();
Thread thread = new Thread(a);
thread.start();
System.out.println("main 休眠10s");
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("通知子线程退出");
a.setExit(false);
}
}

class A implements Runnable{

private boolean exit = true;
@Override
public void run() {
while (exit){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("子线程输出--"+Thread.currentThread().getName());
}
}

public void setExit(boolean exit) {
this.exit = exit;
}
}

线程常用方法

setPriority interrupt setName

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
public class Method3 {
public static void main(String[] args) throws InterruptedException {
T t = new T();
// 设置线程名称
t.setName("子线程");
// 设置优先级
t.setPriority(Thread.MIN_PRIORITY);
t.start();
Thread.sleep(3000);
// 中断休眠
t.interrupt();
}
}

class T extends Thread{
@Override
public void run() {
int i = 0;
while (true){

for (int j = 0; j < 10; j++) {
System.out.println(Thread.currentThread().getName() + (i++));
}

try {
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("休眠被终止");
}
}
}
}

join

  • 强制执行完毕子线程
    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
    public class Method4 {
    public static void main(String[] args) throws InterruptedException {
    Son son = new Son();
    son.start();

    for (int i = 0; i < 20; i++) {
    Thread.sleep(1000);
    System.out.println("主线程"+i);

    if(i == 5){
    System.out.println("主动让出子线程");
    son.join();
    System.out.println("子线程执行完毕");
    }
    }
    }
    }

    class Son extends Thread{
    @Override
    public void run() {
    for (int i = 0; i < 20; i++) {
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }
    System.out.println("子线程"+i);
    }
    }
    }

yield

  • 礼让线程,主动让出当前执行权限,但不一定成功,只有资源紧张时才会礼让成功

用户(工作)线程、守护线程

  • 工作线程:只有任务完成或者被通知结束时才会退出
  • 守护线程:当工作线程全部完成或者退出后,守护线程跟着一起退出
    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
    public class Method5 {
    public static void main(String[] args) throws InterruptedException {
    TDemo tDemo = new TDemo();
    // 设置为守护线程
    tDemo.setDaemon(true);
    tDemo.start();

    for (int i = 0; i < 10; i++) {
    Thread.sleep(1000);
    System.out.println("主线程工作中。。。");
    }

    }
    }

    class TDemo extends Thread{
    @Override
    public void run() {
    while (true){
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }
    System.out.println("子线程正在工作···");
    }
    }
    }

线程的状态

六种:New、Wait、TimeWait、Runnable、Blocked、Terminated

同步操作

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Method6 {
public static void main(String[] args) {
Ticket ticket = new Ticket();
(new Thread(ticket,"售票员1")).start();
(new Thread(ticket,"售票员2")).start();
(new Thread(ticket,"售票员3")).start();
(new Thread(ticket,"售票员4")).start();
(new Thread(ticket,"售票员5")).start();
}
}

class Ticket implements Runnable{
private int num = 100;

// 方法上加锁
public synchronized void soldMethod(){
num --;
System.out.println(Thread.currentThread().getName()+"卖出一张票,票量剩余数:" + num);
}

// 对对象加锁在代码块上
public void soldSelf(){
synchronized(this){
num --;
System.out.println(Thread.currentThread().getName()+"卖出一张票,票量剩余数:" + num);
}
}

// 或者写成
Object obj = new Object();
public void soldObj(){
synchronized(obj){
num --;
System.out.println(Thread.currentThread().getName()+"卖出一张票,票量剩余数:" + num);
}
}

@Override
public void run() {

while (num > 0){

sold();

try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}

}

}
}
  • 静态方法被 synchronized 修饰时,同步锁是加到类本身的 即 this
  • 非静态方法被 synchronized 修饰时,同步锁时加在对象上的 即 当前类.class