java多线程笔记

java多线程笔记01

普通方式加锁 synchronized

多线程判断用while,否则有虚假唤醒的问题

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

// 普通方式加锁 synchronized

public synchronized void increment(){
String threadName = Thread.currentThread().getName();
while (number !=0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
++number;
System.out.println(threadName + "-->" + number);
// 通知
this.notifyAll();
}

public synchronized void decrement(){
String threadName = Thread.currentThread().getName();
while (number == 0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
--number;
System.out.println(threadName + "-->" + number);
// 通知
this.notifyAll();

}

ReentrantLock 锁

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

//ReentrantLock 锁 -- 他还有读写锁,读可以所有的读,写只能一个写(互斥)
package com.cdinit;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ShareData {
private int number = 0;

private Lock lock = new ReentrantLock(); // 1.new ReentrantLock

private Condition condition = lock.newCondition(); // 2. 获取newCondition

public void increment() {
String threadName = Thread.currentThread().getName();
// System.out.println("Increment Thread --> " + Thread.currentThread().getName());
lock.lock(); // 3.lock
try{
while (number != 0){
try {
condition.await(); // 注意是await
} catch (InterruptedException e) {
e.printStackTrace();
}
}
++number;
System.out.println(threadName + " increment-->" + number);
// 通知 必须获得锁
condition.signalAll();
}finally {
lock.unlock();
}

}

public void decrement() {
String threadName = Thread.currentThread().getName();
// System.out.println("Decrement Thread --> " + Thread.currentThread().getName());
lock.lock();
try{
while (number == 0){
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
--number;
System.out.println(threadName + " Decrement-->" + number);
// 通知 必须获得锁
condition.signalAll();
}finally {
lock.unlock();
}
}
}
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

package com.cdinit;

public class ApplicationMain {

public static void main(String[] args) {

ShareData shareData = new ShareData();
new Thread(() -> {
for(int i=0;i<100;i++){
shareData.decrement();
}
},"T1").start();

new Thread(() -> {
for(int i=0;i<100;i++){
shareData.increment();
}
},"T2").start();
new Thread(() -> {
for(int i=0;i<100;i++){
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
shareData.decrement();
}
},"T3").start();

new Thread(() -> {
for(int i=0;i<100;i++){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
shareData.increment();
}
},"T4").start();
}

}

锁静态方法就是锁.class ,锁普通方法是锁this

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

package com.cdinit;

import java.util.concurrent.TimeUnit;

class Phone {
public synchronized void sendSMS() throws Exception{
TimeUnit.SECONDS.sleep(2);
System.out.println("...sendSMS");
}
public synchronized void sendEmail() throws Exception{
System.out.println("...sendEmail");
}
public void openPad(){
System.out.println("...openPad");
}
public static void sendStaticsendSMS() throws Exception{
System.out.println("...sendStaticSMS");
}
public static void sendStaticsendEmail() throws Exception{
TimeUnit.SECONDS.sleep(4);
System.out.println("...sendStaticEmail");
}

}

class Lock_B{
public static void main(String[] args) throws Exception {
Phone phone = new Phone();
new Thread(()->{
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"A").start();

new Thread(()->{
try {
phone.sendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"B").start();

new Thread(()->{
try {
phone.openPad();
} catch (Exception e) {
e.printStackTrace();
}
},"C").start();

new Thread(()->{
try {
Phone.sendStaticsendEmail();
} catch (Exception e) {
e.printStackTrace();
}
},"C").start();

new Thread(()->{
try {
Phone.sendStaticsendSMS();
} catch (Exception e) {
e.printStackTrace();
}
},"C").start();
}
}

ReentrantLock可以做线程调度

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
package com.cdinit;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


class ShareDataSource{
private int number = 1;
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
public void print5(int totalLoop) throws InterruptedException {
lock.lock();
try{
//1 判读
while (number != 1){
c1.await();
}
//2 干活
for(int i=1;i<=5;i++){
System.out.println(Thread.currentThread().getName() + "-->" + i +", total--> "+ totalLoop);
}
//3 通知
number = 2;
c2.signal();
}finally {
lock.unlock();
}
}

public void print10(int totalLoop) throws InterruptedException {
lock.lock();
try{
//1 判读
while (number != 2){
c2.await();
}
//2 干活
for(int i=1;i<=10;i++){
System.out.println(Thread.currentThread().getName() + "--->" + i +", total"+ totalLoop);
}
//3 通知
number = 3;
c3.signal();
}finally {
lock.unlock();
}
}

public void print15(int totalLoop) throws InterruptedException {
lock.lock();
try{
//1 判读
while (number != 3){
c3.await();
}
//2 干活
for(int i=1;i<=15;i++){
System.out.println(Thread.currentThread().getName() + "--->" + i +", total"+ totalLoop);
}
//3 通知
number = 1;
c1.signal();
}finally {
lock.unlock();
}
}

}

public class SeqThread {
public static void main(String args[]) throws Exception{
ShareDataSource shareDataSource = new ShareDataSource();
new Thread(()->{
for(int i=0;i<10;i++){
try {
shareDataSource.print5(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"AA").start();

new Thread(()->{
for(int i=0;i<10;i++){
try {
shareDataSource.print10(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();

new Thread(()->{
for(int i=0;i<10;i++){
try {
shareDataSource.print15(i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"CC").start();
}
}