线程Thread中的join介绍

Posted 霓裳梦竹

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程Thread中的join介绍相关的知识,希望对你有一定的参考价值。

因为sleep、wait、join等阻塞,可以使用interrupted exception异常唤醒。

一、作用

Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行。

package cn.com.upcard;

public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ThreadJoinTest t1 = new ThreadJoinTest("小明");
ThreadJoinTest t2 = new ThreadJoinTest("小东");
t1.start();
/**
* join的意思是使得放弃当前线程的执行,并返回对应的线程,例如如下:
* 程序在main线程中调用t1线程的join方法,则main线程放弃cpu控制权
* ,并返回t1线程继续执行直到线程t1执行完毕,所以结果是t1线程执行完毕后
* ,才到主线程执行,相当于在main线程中同步t1线程,t1执行完了,main线程才有执行的机会。
*/
t1.join();
t2.start();
}
}

class ThreadJoinTest extends Thread {
public ThreadJoinTest(String name) {
super(name);
}

@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(this.getName() + ":" + i);
}
}
}

运行结果:

小明:0
小明: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
小明:61
小明:62
小明:63
小明:64
小明:65
小明:66
小明:67
小明:68
小明:69
小明:70
小明:71
小明:72
小明:73
小明:74
小明:75
小明:76
小明:77
小明:78
小明:79
小明:80
小明:81
小明:82
小明:83
小明:84
小明:85
小明:86
小明:87
小明:88
小明:89
小明:90
小明:91
小明:92
小明:93
小明:94
小明:95
小明:96
小明:97
小明:98
小明:99
小东:0
小东: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
小东:61
小东:62
小东:63
小东:64
小东:65
小东:66
小东:67
小东:68
小东:69
小东:70
小东:71
小东:72
小东:73
小东:74
小东:75
小东:76
小东:77
小东:78
小东:79
小东:80
小东:81
小东:82
小东:83
小东:84
小东:85
小东:86
小东:87
小东:88
小东:89
小东:90
小东:91
小东:92
小东:93
小东:94
小东:95
小东:96
小东:97
小东:98
小东:99

可以看出是先打印完第一个线程,再打印第二个线程。说明:在A线程中调用了B线程的join()方法时,表示只有当B线程执行完毕时,A线程才能继续执行,注意,这里调用的join方法是没有传参的,join方法其实也可以传递一个参数给它。  

 

package cn.com.upcard;

public class ThreadTest {
	public static void main(String[] args) throws InterruptedException {
		ThreadJoinTest t1 = new ThreadJoinTest("小明");
		ThreadJoinTest t2 = new ThreadJoinTest("小东");
		t1.start();
		/**
		 * join方法可以传递参数,join(1)表示线程会等待t1线程1毫秒,1毫秒过去后,main线程和t1线程之间执行顺序由串行执行变为普通的并行执行
		 */
		t1.join(2);
		t2.start();
	}
}

class ThreadJoinTest extends Thread {
	public ThreadJoinTest(String name) {
		super(name);
	}

	@Override
	public void run() {
		for (int i = 0; i < 500; i++) {
			System.out.println(this.getName() + ":" + i);
		}
	}
}  

 

执行结果:

小明:0
小明: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
小明:61
小明:62
小明:63
小明:64
小明:65
小明:66
小明:67
小明:68
小明:69
小明:70
小明:71
小明:72
小明:73
小明:74
小明:75
小明:76
小明:77
小明:78
小明:79
小明:80
小明:81
小明:82
小明:83
小明:84
小明:85
小明:86
小明:87
小明:88
小明:89
小明:90
小明:91
小明:92
小明:93
小明:94
小明:95
小明:96
小明:97
小明:98
小明:99
小明:100
小明:101
小明:102
小明:103
小明:104
小明:105
小明:106
小明:107
小明:108
小明:109
小明:110
小明:111
小明:112
小明:113
小明:114
小明:115
小明:116
小明:117
小明:118
小明:119
小明:120
小明:121
小明:122
小明:123
小明:124
小明:125
小明:126
小明:127
小明:128
小明:129
小明:130
小明:131
小明:132
小明:133
小明:134
小明:135
小明:136
小明:137
小明:138
小明:139
小明:140
小明:141
小明:142
小明:143
小明:144
小明:145
小明:146
小明:147
小明:148
小明:149
小明:150
小明:151
小明:152
小明:153
小明:154
小明:155
小明:156
小明:157
小明:158
小明:159
小明:160
小明:161
小明:162
小明:163
小明:164
小明:165
小明:166
小明:167
小明:168
小明:169
小明:170
小明:171
小明:172
小明:173
小明:174
小明:175
小明:176
小明:177
小明:178
小明:179
小明:180
小明:181
小明:182
小明:183
小明:184
小明:185
小明:186
小明:187
小明:188
小明:189
小明:190
小明:191
小明:192
小明:193
小明:194
小明:195
小明:196
小明:197
小明:198
小明:199
小明:200
小明:201
小明:202
小明:203
小明:204
小明:205
小明:206
小明:207
小明:208
小明:209
小明:210
小明:211
小明:212
小明:213
小明:214
小东:0
小东: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
小东:61
小东:62
小东:63
小东:64
小东:65
小东:66
小东:67
小东:68
小东:69
小东:70
小东:71
小东:72
小东:73
小东:74
小东:75
小东:76
小东:77
小东:78
小东:79
小东:80
小东:81
小东:82
小东:83
小东:84
小东:85
小东:86
小东:87
小东:88
小东:89
小东:90
小东:91
小东:92
小东:93
小东:94
小东:95
小东:96
小东:97
小东:98
小东:99
小东:100
小东:101
小东:102
小东:103
小东:104
小东:105
小东:106
小东:107
小东:108
小东:109
小东:110
小东:111
小东:112
小东:113
小东:114
小东:115
小东:116
小东:117
小东:118
小东:119
小东:120
小东:121
小东:122
小东:123
小东:124
小东:125
小东:126
小东:127
小东:128
小东:129
小东:130
小东:131
小东:132
小东:133
小东:134
小东:135
小东:136
小东:137
小东:138
小东:139
小东:140
小东:141
小东:142
小东:143
小东:144
小东:145
小东:146
小东:147
小东:148
小东:149
小东:150
小东:151
小东:152
小东:153
小东:154
小东:155
小东:156
小东:157
小东:158
小东:159
小东:160
小东:161
小东:162
小东:163
小东:164
小东:165
小东:166
小东:167
小东:168
小东:169
小东:170
小东:171
小东:172
小东:173
小东:174
小东:175
小东:176
小东:177
小东:178
小东:179
小东:180
小东:181
小东:182
小东:183
小东:184
小东:185
小东:186
小东:187
小东:188
小东:189
小东:190
小东:191
小东:192
小东:193
小东:194
小东:195
小东:196
小东:197
小东:198
小东:199
小东:200
小东:201
小东:202
小东:203
小东:204
小东:205
小东:206
小东:207
小东:208
小东:209
小东:210
小东:211
小东:212
小东:213
小东:214
小东:215
小东:216
小东:217
小东:218
小东:219
小东:220
小东:221
小东:222
小东:223
小东:224
小东:225
小东:226
小东:227
小东:228
小东:229
小东:230
小东:231
小东:232
小东:233
小东:234
小东:235
小东:236
小东:237
小东:238
小东:239
小东:240
小东:241
小东:242
小东:243
小东:244
小东:245
小东:246
小东:247
小东:248
小东:249
小东:250
小东:251
小东:252
小东:253
小东:254
小东:255
小东:256
小东:257
小东:258
小东:259
小东:260
小东:261
小东:262
小东:263
小东:264
小东:265
小东:266
小东:267
小东:268
小东:269
小东:270
小东:271
小东:272
小东:273
小东:274
小东:275
小东:276
小东:277
小东:278
小东:279
小东:280
小东:281
小东:282
小东:283
小东:284
小东:285
小东:286
小东:287
小东:288
小明:215
小明:216
小明:217
小明:218
小明:219
小明:220
小明:221
小明:222
小明:223
小明:224
小明:225
小明:226
小明:227
小明:228
小明:229
小明:230
小明:231
小明:232
小明:233
小明:234
小明:235
小明:236
小明:237
小明:238
小明:239
小明:240
小明:241
小明:242
小明:243
小明:244
小明:245
小明:246
小明:247
小明:248
小明:249
小明:250
小明:251
小明:252
小明:253
小明:254
小明:255
小明:256
小明:257
小明:258
小明:259
小明:260
小明:261
小明:262
小明:263
小明:264
小明:265
小明:266
小明:267
小明:268
小明:269
小明:270
小明:271
小明:272
小明:273
小明:274
小明:275
小明:276
小明:277
小明:278
小明:279
小明:280
小明:281
小明:282
小明:283
小明:284
小明:285
小明:286
小明:287
小明:288
小明:289
小明:290
小明:291
小明:292
小明:293
小明:294
小明:295
小明:296
小明:297
小明:298
小明:299
小明:300
小明:301
小明:302
小明:303
小明:304
小明:305
小明:306
小明:307
小明:308
小明:309
小明:310
小明:311
小明:312
小明:313
小明:314
小明:315
小明:316
小明:317
小明:318
小明:319
小明:320
小明:321
小明:322
小明:323
小明:324
小明:325
小明:326
小明:327
小明:328
小明:329
小明:330
小明:331
小明:332
小明:333
小明:334
小明:335
小明:336
小明:337
小明:338
小明:339
小明:340
小明:341
小明:342
小明:343
小明:344
小明:345
小明:346
小明:347
小明:348
小明:349
小明:350
小明:351
小明:352
小明:353
小明:354
小明:355
小明:356
小明:357
小明:358
小明:359
小明:360
小明:361
小明:362
小明:363
小明:364
小明:365
小明:366
小明:367
小明:368
小明:369
小明:370
小明:371
小明:372
小明:373
小明:374
小明:375
小明:376
小明:377
小明:378
小明:379
小明:380
小明:381
小明:382
小明:383
小明:384
小明:385
小明:386
小明:387
小明:388
小明:389
小明:390
小明:391
小明:392
小明:393
小明:394
小明:395
小明:396
小明:397
小明:398
小明:399
小明:400
小明:401
小明:402
小明:403
小明:404
小明:405
小明:406
小明:407
小明:408
小明:409
小明:410
小明:411
小明:412
小明:413
小明:414
小明:415
小明:416
小明:417
小明:418
小明:419
小明:420
小明:421
小明:422
小明:423
小明:424
小明:425
小明:426
小明:427
小明:428
小明:429
小明:430
小明:431
小明:432
小明:433
小明:434
小明:435
小明:436
小明:437
小明:438
小明:439
小明:440
小明:441
小明:442
小明:443
小明:444
小明:445
小明:446
小明:447
小明:448
小明:449
小明:450
小明:451
小明:452
小明:453
小明:454
小明:455
小明:456
小明:457
小明:458
小明:459
小明:460
小明:461
小明:462
小明:463
小明:464
小明:465
小明:466
小明:467
小明:468
小明:469
小明:470
小明:471
小明:472
小明:473
小明:474
小明:475
小明:476
小明:477
小明:478
小明:479
小明:480
小明:481
小明:482
小明:483
小明:484
小明:485
小明:486
小明:487
小明:488
小明:489
小明:490
小明:491
小明:492
小明:493
小明:494
小明:495
小明:496
小明:497
小明:498
小明:499
小东:289
小东:290
小东:291
小东:292
小东:293
小东:294
小东:295
小东:296
小东:297
小东:298
小东:299
小东:300
小东:301
小东:302
小东:303
小东:304
小东:305
小东:306
小东:307
小东:308
小东:309
小东:310
小东:311
小东:312
小东:313
小东:314
小东:315
小东:316
小东:317
小东:318
小东:319
小东:320
小东:321
小东:322
小东:323
小东:324
小东:325
小东:326
小东:327
小东:328
小东:329
小东:330
小东:331
小东:332
小东:333
小东:334
小东:335
小东:336
小东:337
小东:338
小东:339
小东:340
小东:341
小东:342
小东:343
小东:344
小东:345
小东:346
小东:347
小东:348
小东:349
小东:350
小东:351
小东:352
小东:353
小东:354
小东:355
小东:356
小东:357
小东:358
小东:359
小东:360
小东:361
小东:362
小东:363
小东:364
小东:365
小东:366
小东:367
小东:368
小东:369
小东:370
小东:371
小东:372
小东:373
小东:374
小东:375
小东:376
小东:377
小东:378
小东:379
小东:380
小东:381
小东:382
小东:383
小东:384
小东:385
小东:386
小东:387
小东:388
小东:389
小东:390
小东:391
小东:392
小东:393
小东:394
小东:395
小东:396
小东:397
小东:398
小东:399
小东:400
小东:401
小东:402
小东:403
小东:404
小东:405
小东:406
小东:407
小东:408
小东:409
小东:410
小东:411
小东:412
小东:413
小东:414
小东:415
小东:416
小东:417
小东:418
小东:419
小东:420
小东:421
小东:422
小东:423
小东:424
小东:425
小东:426
小东:427
小东:428
小东:429
小东:430
小东:431
小东:432
小东:433
小东:434
小东:435
小东:436
小东:437
小东:438
小东:439
小东:440
小东:441
小东:442
小东:443
小东:444
小东:445
小东:446
小东:447
小东:448
小东:449
小东:450
小东:451
小东:452
小东:453
小东:454
小东:455
小东:456
小东:457
小东:458
小东:459
小东:460
小东:461
小东:462
小东:463
小东:464
小东:465
小东:466
小东:467
小东:468
小东:469
小东:470
小东:471
小东:472
小东:473
小东:474
小东:475
小东:476
小东:477
小东:478
小东:479
小东:480
小东:481
小东:482
小东:483
小东:484
小东:485
小东:486
小东:487
小东:488
小东:489
小东:490
小东:491
小东:492
小东:493
小东:494
小东:495
小东:496
小东:497
小东:498
小东:499

  

前2毫秒打印的都是第一个线程,之后是交替打印。

所以,join方法中如果传入参数,则表示这样的意思:如果A线程中掉用B线程的join(10),则表示A线程会等待B线程执行10毫秒,10毫秒过后,A、B线程并行执行。需要注意的是,jdk规定,join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕,即join(0)等价于join()。

二、join和start调用顺序对结果的影响

package cn.com.upcard;

public class ThreadTest {
	public static void main(String[] args) throws InterruptedException {
		ThreadJoinTest t1 = new ThreadJoinTest("小明");
		ThreadJoinTest t2 = new ThreadJoinTest("小东");
		
		/**
		 * join方法在start之前调用,并不能起到同步的作用
		 */
		t1.join();
		t1.start();
		t2.start();
	}
}

class ThreadJoinTest extends Thread {
	public ThreadJoinTest(String name) {
		super(name);
	}

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			System.out.println(this.getName() + ":" + i);
		}
	}
}
小明:0
小明: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
小东:0
小明:33
小东:1
小明:34
小东:2
小明:35
小东:3
小明:36
小明:37
小东:4
小明:38
小东:5
小明:39
小东:6
小明:40
小东: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
小明:41
小东: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
小东:61
小东:62
小东:63
小东:64
小东:65
小东:66
小东:67
小东:68
小东:69
小东:70
小东:71
小东:72
小东:73
小东:74
小东:75
小东:76
小东:77
小东:78
小东:79
小东:80
小东:81
小东:82
小东:83
小东:84
小东:85
小东:86
小东:87
小东:88
小东:89
小东:90
小东:91
小东:92
小东:93
小东:94
小东:95
小东:96
小东:97
小东:98
小东:99
小明:42
小明:43
小明:44
小明:45
小明:46
小明:47
小明:48
小明:49
小明:50
小明:51
小明:52
小明:53
小明:54
小明:55
小明:56
小明:57
小明:58
小明:59
小明:60
小明:61
小明:62
小明:63
小明:64
小明:65
小明:66
小明:67
小明:68
小明:69
小明:70
小明:71
小明:72
小明:73
小明:74
小明:75
小明:76
小明:77
小明:78
小明:79
小明:80
小明:81
小明:82
小明:83
小明:84
小明:85
小明:86
小明:87
小明:88
小明:89
小明:90
小明:91
小明:92
小明:93
小明:94
小明:95
小明:96
小明:97
小明:98
小明:99 

可以看到执行结果为:小明和小东线程交替打印

因此,join方法必须在线程start方法调用之后调用才有意义。

三、实现原理

public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

  

由上可以看出,join方法的原理是调用相应线程的wait方法进行等待操作的。

 

 

 

 

 

 

 

  

 

以上是关于线程Thread中的join介绍的主要内容,如果未能解决你的问题,请参考以下文章

使用 threading.Thread.join()

pthread_join的介绍

Thread线程join方法自我理解

Thread中的join使用

浅析Thread的join() 方法

Java多线程中的join方法