`

多线程课程001:线程安全的问题

 
阅读更多
下面的做法,会发现输出结果被打断了。
package com.lee.thread;

//子线程循环10次,主线程循环100次,接着又到子线程循环10次,接着又到主线程循环100次,如此反复50次
public class TraditionalThreadComunication {

	public static void main(String[] args) {
		// 子线程
		new Thread(new Runnable() {
			@Override
			public void run() {

				for (int i = 1; i <= 50; i++) {
					for (int j = 1; j <= 10; j++) {
						System.out.println("sub: " + j + " loop: " + i);
					}
				}

			}
		}).start();

		// 主线程
		for (int i = 1; i <= 50; i++) {
			for (int j = 1; j <= 10; j++) {
				System.out.println("main: " + j + " loop: " + i);
			}
		}
	}

}


main应该执行完10次才到sub的,可是被打断了
main: 1 loop: 1
main: 2 loop: 1
sub: 1 loop: 1
sub: 2 loop: 1
main: 3 loop: 1
sub: 3 loop: 1


子线程和主线程加了字节码的锁,形成了互斥,但并非一人一次。

//子线程循环10次,主线程循环100次,接着又到子线程循环10次,接着又到主线程循环100次,如此反复50次
public class TraditionalThreadComunication {

	public static void main(String[] args) {
		// 子线程
		new Thread(new Runnable() {
			@Override
			public void run() {

				for (int i = 1; i <= 50; i++) {
					synchronized (TraditionalThreadComunication.class) { 
						for (int j = 1; j <= 10; j++) {
							System.out.println("sub: " + j + " loop: " + i);
						}
					}					
				}

			}
		}).start();

		// 主线程
		for (int i = 1; i <= 50; i++) {
			synchronized (TraditionalThreadComunication.class){
				for (int j = 1; j <= 10; j++) {
					System.out.println("main: " + j + " loop: " + i);
				}
			}
		}
	}

}


main: 1 loop: 1
main: 2 loop: 1
main: 3 loop: 1
main: 4 loop: 1
main: 5 loop: 1
main: 6 loop: 1
main: 7 loop: 1
main: 8 loop: 1
main: 9 loop: 1
main: 10 loop: 1
main: 1 loop: 2
main: 2 loop: 2
main: 3 loop: 2
main: 4 loop: 2
main: 5 loop: 2
main: 6 loop: 2
main: 7 loop: 2
main: 8 loop: 2
main: 9 loop: 2
main: 10 loop: 2
main: 1 loop: 3
main: 2 loop: 3
main: 3 loop: 3
main: 4 loop: 3
main: 5 loop: 3
main: 6 loop: 3
main: 7 loop: 3
main: 8 loop: 3
main: 9 loop: 3
main: 10 loop: 3
main: 1 loop: 4
main: 2 loop: 4
main: 3 loop: 4
main: 4 loop: 4
main: 5 loop: 4
main: 6 loop: 4
main: 7 loop: 4
main: 8 loop: 4
main: 9 loop: 4
main: 10 loop: 4
sub: 1 loop: 1
sub: 2 loop: 1
sub: 3 loop: 1
sub: 4 loop: 1
sub: 5 loop: 1
sub: 6 loop: 1
sub: 7 loop: 1
sub: 8 loop: 1
sub: 9 loop: 1
sub: 10 loop: 1
sub: 1 loop: 2
sub: 2 loop: 2
sub: 3 loop: 2
sub: 4 loop: 2
sub: 5 loop: 2
sub: 6 loop: 2
sub: 7 loop: 2
sub: 8 loop: 2


把线程锁封装到方法体里边,这个时候,可以看到主函数中,并没有线程锁,所以,线程锁是主函数中的一部分,因此,循环也应该是循环后再控制同步
package com.lee.thread;

//子线程循环10次,主线程循环100次,接着又到子线程循环10次,接着又到主线程循环100次,如此反复50次
public class TraditionalThreadComunication {

	public static void main(String[] args) {
		
		final Business business = new Business();	
		
		// 子线程
		new Thread(new Runnable() {
			@Override
			public void run() {

				for (int i = 1; i <= 50; i++) {
					business.sub(i);
				}

			}
		}).start();

		// 主线程
		for (int i = 1; i <= 50; i++) {
			business.main(i);
		}
	}

}

class Business{
	public synchronized void sub(int i){
			for (int j = 1; j <= 10; j++) {
				System.out.println("sub: " + j + " loop: " + i);
			}		
	}
	
	public synchronized void main(int i){
			for (int j = 1; j <= 10; j++) {
				System.out.println("main: " + j + " loop: " + i);
			}
	}
}


main: 1 loop: 3
main: 2 loop: 3
main: 3 loop: 3
main: 4 loop: 3
main: 5 loop: 3
main: 6 loop: 3
main: 7 loop: 3
main: 8 loop: 3
main: 9 loop: 3
main: 10 loop: 3
main: 1 loop: 4
main: 2 loop: 4
main: 3 loop: 4
main: 4 loop: 4
main: 5 loop: 4
main: 6 loop: 4
main: 7 loop: 4
main: 8 loop: 4
main: 9 loop: 4
main: 10 loop: 4
main: 1 loop: 5
main: 2 loop: 5
main: 3 loop: 5
main: 4 loop: 5
main: 5 loop: 5
main: 6 loop: 5
main: 7 loop: 5
main: 8 loop: 5
main: 9 loop: 5
main: 10 loop: 5
main: 1 loop: 6
main: 2 loop: 6
main: 3 loop: 6
main: 4 loop: 6
main: 5 loop: 6
main: 6 loop: 6
main: 7 loop: 6
main: 8 loop: 6
main: 9 loop: 6
main: 10 loop: 6
main: 1 loop: 7
main: 2 loop: 7
main: 3 loop: 7
main: 4 loop: 7
main: 5 loop: 7
main: 6 loop: 7
main: 7 loop: 7
main: 8 loop: 7
main: 9 loop: 7
main: 10 loop: 7
main: 1 loop: 8
main: 2 loop: 8
main: 3 loop: 8
main: 4 loop: 8
main: 5 loop: 8
main: 6 loop: 8
main: 7 loop: 8
main: 8 loop: 8
main: 9 loop: 8
main: 10 loop: 8
main: 1 loop: 9
main: 2 loop: 9
main: 3 loop: 9
main: 4 loop: 9
main: 5 loop: 9
main: 6 loop: 9
main: 7 loop: 9
main: 8 loop: 9
main: 9 loop: 9
main: 10 loop: 9
main: 1 loop: 10
main: 2 loop: 10
main: 3 loop: 10
main: 4 loop: 10
main: 5 loop: 10
main: 6 loop: 10
main: 7 loop: 10
main: 8 loop: 10
main: 9 loop: 10
main: 10 loop: 10
main: 1 loop: 11
main: 2 loop: 11
main: 3 loop: 11
main: 4 loop: 11
main: 5 loop: 11
main: 6 loop: 11
main: 7 loop: 11
main: 8 loop: 11
main: 9 loop: 11
main: 10 loop: 11
main: 1 loop: 12
main: 2 loop: 12
main: 3 loop: 12
main: 4 loop: 12
main: 5 loop: 12
main: 6 loop: 12
main: 7 loop: 12
main: 8 loop: 12
main: 9 loop: 12
main: 10 loop: 12
main: 1 loop: 13
main: 2 loop: 13
main: 3 loop: 13
main: 4 loop: 13
main: 5 loop: 13
main: 6 loop: 13
main: 7 loop: 13
main: 8 loop: 13
main: 9 loop: 13
main: 10 loop: 13
main: 1 loop: 14
main: 2 loop: 14
main: 3 loop: 14
main: 4 loop: 14
main: 5 loop: 14
main: 6 loop: 14
main: 7 loop: 14
main: 8 loop: 14
main: 9 loop: 14
main: 10 loop: 14
main: 1 loop: 15
main: 2 loop: 15
main: 3 loop: 15
main: 4 loop: 15
main: 5 loop: 15
main: 6 loop: 15
main: 7 loop: 15
main: 8 loop: 15
main: 9 loop: 15
main: 10 loop: 15
main: 1 loop: 16
main: 2 loop: 16
main: 3 loop: 16
main: 4 loop: 16
main: 5 loop: 16
main: 6 loop: 16
main: 7 loop: 16
main: 8 loop: 16
main: 9 loop: 16
main: 10 loop: 16
main: 1 loop: 17
main: 2 loop: 17
main: 3 loop: 17
main: 4 loop: 17
main: 5 loop: 17
main: 6 loop: 17
main: 7 loop: 17
main: 8 loop: 17
main: 9 loop: 17
main: 10 loop: 17
main: 1 loop: 18
main: 2 loop: 18
main: 3 loop: 18
main: 4 loop: 18
main: 5 loop: 18
main: 6 loop: 18
main: 7 loop: 18
main: 8 loop: 18
main: 9 loop: 18
main: 10 loop: 18
main: 1 loop: 19
main: 2 loop: 19
main: 3 loop: 19
main: 4 loop: 19
main: 5 loop: 19
main: 6 loop: 19
main: 7 loop: 19
main: 8 loop: 19
main: 9 loop: 19
main: 10 loop: 19
main: 1 loop: 20
main: 2 loop: 20
main: 3 loop: 20
main: 4 loop: 20
main: 5 loop: 20
main: 6 loop: 20
main: 7 loop: 20
main: 8 loop: 20
main: 9 loop: 20
main: 10 loop: 20
main: 1 loop: 21
main: 2 loop: 21
main: 3 loop: 21
main: 4 loop: 21
main: 5 loop: 21
main: 6 loop: 21
main: 7 loop: 21
main: 8 loop: 21
main: 9 loop: 21
main: 10 loop: 21
main: 1 loop: 22
main: 2 loop: 22
main: 3 loop: 22
main: 4 loop: 22
main: 5 loop: 22
main: 6 loop: 22
main: 7 loop: 22
main: 8 loop: 22
main: 9 loop: 22
main: 10 loop: 22
main: 1 loop: 23
main: 2 loop: 23
main: 3 loop: 23
main: 4 loop: 23
main: 5 loop: 23
main: 6 loop: 23
main: 7 loop: 23
main: 8 loop: 23
main: 9 loop: 23
main: 10 loop: 23
main: 1 loop: 24
main: 2 loop: 24
main: 3 loop: 24
main: 4 loop: 24
main: 5 loop: 24
main: 6 loop: 24
main: 7 loop: 24
main: 8 loop: 24
main: 9 loop: 24
main: 10 loop: 24
main: 1 loop: 25
main: 2 loop: 25
main: 3 loop: 25
main: 4 loop: 25
main: 5 loop: 25
main: 6 loop: 25
main: 7 loop: 25
main: 8 loop: 25
main: 9 loop: 25
main: 10 loop: 25
main: 1 loop: 26
main: 2 loop: 26
main: 3 loop: 26
main: 4 loop: 26
main: 5 loop: 26
main: 6 loop: 26
main: 7 loop: 26
main: 8 loop: 26
main: 9 loop: 26
main: 10 loop: 26
main: 1 loop: 27
main: 2 loop: 27
main: 3 loop: 27
main: 4 loop: 27
main: 5 loop: 27
main: 6 loop: 27
main: 7 loop: 27
main: 8 loop: 27
main: 9 loop: 27
main: 10 loop: 27
main: 1 loop: 28
main: 2 loop: 28
main: 3 loop: 28
main: 4 loop: 28
main: 5 loop: 28
main: 6 loop: 28
main: 7 loop: 28
main: 8 loop: 28
main: 9 loop: 28
main: 10 loop: 28
main: 1 loop: 29
main: 2 loop: 29
main: 3 loop: 29
main: 4 loop: 29
main: 5 loop: 29
main: 6 loop: 29
main: 7 loop: 29
main: 8 loop: 29
main: 9 loop: 29
main: 10 loop: 29
main: 1 loop: 30
main: 2 loop: 30
main: 3 loop: 30
main: 4 loop: 30
main: 5 loop: 30
main: 6 loop: 30
main: 7 loop: 30
main: 8 loop: 30
main: 9 loop: 30
main: 10 loop: 30
main: 1 loop: 31
main: 2 loop: 31
main: 3 loop: 31
main: 4 loop: 31
main: 5 loop: 31
main: 6 loop: 31
main: 7 loop: 31
main: 8 loop: 31
main: 9 loop: 31
main: 10 loop: 31
main: 1 loop: 32
main: 2 loop: 32
main: 3 loop: 32
main: 4 loop: 32
main: 5 loop: 32
main: 6 loop: 32
main: 7 loop: 32
main: 8 loop: 32
main: 9 loop: 32
main: 10 loop: 32
main: 1 loop: 33
main: 2 loop: 33
main: 3 loop: 33
main: 4 loop: 33
main: 5 loop: 33
main: 6 loop: 33
main: 7 loop: 33
main: 8 loop: 33
main: 9 loop: 33
main: 10 loop: 33
main: 1 loop: 34
main: 2 loop: 34
main: 3 loop: 34
main: 4 loop: 34
main: 5 loop: 34
main: 6 loop: 34
main: 7 loop: 34
main: 8 loop: 34
main: 9 loop: 34
main: 10 loop: 34
main: 1 loop: 35
main: 2 loop: 35
main: 3 loop: 35
main: 4 loop: 35
main: 5 loop: 35
main: 6 loop: 35
main: 7 loop: 35
main: 8 loop: 35
main: 9 loop: 35
main: 10 loop: 35
main: 1 loop: 36
main: 2 loop: 36
main: 3 loop: 36
main: 4 loop: 36
main: 5 loop: 36
main: 6 loop: 36
main: 7 loop: 36
main: 8 loop: 36
main: 9 loop: 36
main: 10 loop: 36
main: 1 loop: 37
main: 2 loop: 37
main: 3 loop: 37
main: 4 loop: 37
main: 5 loop: 37
main: 6 loop: 37
main: 7 loop: 37
main: 8 loop: 37
main: 9 loop: 37
main: 10 loop: 37
main: 1 loop: 38
main: 2 loop: 38
main: 3 loop: 38
main: 4 loop: 38
main: 5 loop: 38
main: 6 loop: 38
main: 7 loop: 38
main: 8 loop: 38
main: 9 loop: 38
main: 10 loop: 38
main: 1 loop: 39
main: 2 loop: 39
main: 3 loop: 39
main: 4 loop: 39
main: 5 loop: 39
main: 6 loop: 39
main: 7 loop: 39
main: 8 loop: 39
main: 9 loop: 39
main: 10 loop: 39
main: 1 loop: 40
main: 2 loop: 40
main: 3 loop: 40
main: 4 loop: 40
main: 5 loop: 40
main: 6 loop: 40
main: 7 loop: 40
main: 8 loop: 40
main: 9 loop: 40
main: 10 loop: 40
main: 1 loop: 41
main: 2 loop: 41
main: 3 loop: 41
main: 4 loop: 41
main: 5 loop: 41
main: 6 loop: 41
main: 7 loop: 41
main: 8 loop: 41
main: 9 loop: 41
main: 10 loop: 41
main: 1 loop: 42
main: 2 loop: 42
main: 3 loop: 42
main: 4 loop: 42
main: 5 loop: 42
main: 6 loop: 42
main: 7 loop: 42
main: 8 loop: 42
main: 9 loop: 42
main: 10 loop: 42
main: 1 loop: 43
main: 2 loop: 43
main: 3 loop: 43
main: 4 loop: 43
main: 5 loop: 43
main: 6 loop: 43
main: 7 loop: 43
main: 8 loop: 43
main: 9 loop: 43
main: 10 loop: 43
main: 1 loop: 44
main: 2 loop: 44
main: 3 loop: 44
main: 4 loop: 44
main: 5 loop: 44
main: 6 loop: 44
main: 7 loop: 44
main: 8 loop: 44
main: 9 loop: 44
main: 10 loop: 44
main: 1 loop: 45
main: 2 loop: 45
main: 3 loop: 45
main: 4 loop: 45
main: 5 loop: 45
main: 6 loop: 45
main: 7 loop: 45
main: 8 loop: 45
main: 9 loop: 45
main: 10 loop: 45
main: 1 loop: 46
main: 2 loop: 46
main: 3 loop: 46
main: 4 loop: 46
main: 5 loop: 46
main: 6 loop: 46
main: 7 loop: 46
main: 8 loop: 46
main: 9 loop: 46
main: 10 loop: 46
main: 1 loop: 47
main: 2 loop: 47
main: 3 loop: 47
main: 4 loop: 47
main: 5 loop: 47
main: 6 loop: 47
main: 7 loop: 47
main: 8 loop: 47
main: 9 loop: 47
main: 10 loop: 47
main: 1 loop: 48
main: 2 loop: 48
main: 3 loop: 48
main: 4 loop: 48
main: 5 loop: 48
main: 6 loop: 48
main: 7 loop: 48
main: 8 loop: 48
main: 9 loop: 48
main: 10 loop: 48
main: 1 loop: 49
main: 2 loop: 49
main: 3 loop: 49
main: 4 loop: 49
main: 5 loop: 49
main: 6 loop: 49
main: 7 loop: 49
main: 8 loop: 49
main: 9 loop: 49
main: 10 loop: 49
main: 1 loop: 50
main: 2 loop: 50
main: 3 loop: 50
main: 4 loop: 50
main: 5 loop: 50
main: 6 loop: 50
main: 7 loop: 50
main: 8 loop: 50
main: 9 loop: 50
main: 10 loop: 50
sub: 1 loop: 1
sub: 2 loop: 1
sub: 3 loop: 1
sub: 4 loop: 1


实现了一来一往互斥效果

synchronized method:
whili(!){
this.wait();
}
false;
this.notify();

synchronized method:
while(){
this.wait();
}
false;
this.notify();

package com.lee.thread;

//子线程循环10次,主线程循环100次,接着又到子线程循环10次,接着又到主线程循环100次,如此反复50次
public class TraditionalThreadComunication {

	public static void main(String[] args) throws Exception {

		final Business business = new Business();

		// 子线程
		new Thread(new Runnable() {
			@Override
			public void run() {

				for (int i = 1; i <= 50; i++) {
					try {
						business.sub(i);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

			}
		}).start();

		// 主线程
		for (int i = 1; i <= 50; i++) {
			business.main(i);
		}
	}

}

class Business {
	// sub与main已经互斥了
	private boolean bShouldSub = true;

	// 1.2如果来的是子线程,不用等待,直接输出,然后唤醒对方,bShouldSub = false;
	// 1.4如果来的是子线程,不用等待,直接输出,然后唤醒对方,
	// 1.5如果来的是子线程,那么等待。
	public synchronized void sub(int i) throws Exception {
		while (!bShouldSub) {
			this.wait();
		}
		for (int j = 1; j <= 10; j++) {
			System.out.println("sub: " + j + " loop: " + i);
		}
		bShouldSub = false;
		this.notify();

	}

	// 1.1如果来的是主线程,那么等待。
	// 1.3如果来的是主线程,直接输出,bShouldSub = true,唤醒对方
	public synchronized void main(int i) throws Exception {
		while (bShouldSub) {
			this.wait();
		}
		for (int j = 1; j <= 10; j++) {
			System.out.println("main: " + j + " loop: " + i);
		}
		bShouldSub = true;
		this.notify();
	}
}




main thread sequence of 98,loop of 32
main thread sequence of 99,loop of 32
main thread sequence of 100,loop of 32
sub thread sequence of 1,loop of 33
sub thread sequence of 2,loop of 33
sub thread sequence of 3,loop of 33
sub thread sequence of 4,loop of 33
sub thread sequence of 5,loop of 33
sub thread sequence of 6,loop of 33
sub thread sequence of 7,loop of 33
sub thread sequence of 8,loop of 33
sub thread sequence of 9,loop of 33
sub thread sequence of 10,loop of 33
main thread sequence of 1,loop of 33
main thread sequence of 2,loop of 33

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics