您的位置:首页 > 编程语言 > Java开发

java线程研究---(8)Thread同步:锁的概念

2015-09-02 11:47 477 查看
(多线程数据共用的)示例代码:

先来看看“java线程研究---(7)Thread同步:多线程数据共用会产生问题”这篇文章里面主要的代码例子

ShareDataThread.java

package thread;

public class ShareDataThread implements Runnable {

	private int i = 0;

	@Override
	public void run() {
		while (i < 10) {
			i++;
			for (int j = 0; j < 10000000l; j++)
				;
			System.out.println(Thread.currentThread().getName() + ": " + i);
		}
	}
}


OneObjExample.java

package thread;

public class OneObjExample {
	
	public static void main(String abc[]) {

		ShareDataThread s1 = new ShareDataThread();
		
		Thread t1 = new Thread(s1);
		Thread t2 = new Thread(s1);
		
		t1.start();
		t2.start();
	}
}


运行结果(其实每次运行结果都不一样的,如下结果只不过是典型的一次结果):
Thread-1: 1

Thread-1: 3

Thread-0: 4

Thread-1: 5

Thread-0: 6

Thread-1: 7

Thread-1: 8

Thread-0: 9

Thread-1: 10

Thread-0: 10

分析运行结果:

我就如上的结果,有如下的分析(或者说猜测,因为多线程这东西,只能根据现象去揣测,无从得知底这两个线程是如何交替运行的

):

为什么2没有打印出来?

thread-1打印1完毕之后,
thread-1继续执行i++
thread-1接着执行for循环,由于执行for循环需要较长的时间,
thread-1还没有来得及打印2,thread-1就被cpu替换下来了。。。
thread-0开始执行,此时thread-0所拿到的i=2,
thread-0,在执行i++之后,i=3
thread-0接着执行for循环,由于执行for循环需要较长的时间,
thread-0还没有来得及打印3,thread-0就被cpu替换下来了。。。

thread-1开始执行,此时thread-1所拿到的i=3,
注意,此时thread-1是继续上一次他被cpu替换下来的点继续执行,所以

thread-1直接开始打印3!
大家多读读几遍,看看我分析的对不?

为什么打印两个10?

其实也很好分析
Thread-1,在要打印之前,被cpu替换下来
Thread-1再被cpu调用,开始执行的时候,所拿到的i=10。由于是继续上一次代码行号执行,所以

Thread-1执行打印10。
Thread-1继续while循环,但是条件不成立,while循环结束,Thread-1进入死亡状态。
Thread-0,也是在要打印之前,被cpu替换下来
Thread-0再被cpu调用,开始执行的时候,所拿到的i依旧是10。由于是继续上一次代码行号执行,所以
Thread-0执行打印10。
Thread-0继续while循环,但是条件不成立,while循环结束,Thread-0也进入死亡状态。
小妹分析的太深入了,有木有


结论总结:
针对于这个示例代码,和打印的结果,综合分析,我的总结就是:

i++
for循环
打印
这三行代码,只要被其他线程进来,分割,侵入,就会造成数据打印不一致的结果。
因此,得让这三行代码,具有原子性!不可分割,无法被其他线程进来侵入,打断这三行代码连续执行
所以给这三行代码加锁,那么这三行代码就变成了一个整体,具有原子性!
好啦,锁的概念,由此诞生!

锁:synchronized

之前的文字,都是为了现在,引入锁的概念,为什么有锁,加锁的目的等——锁就是为了解决多线程的数据同步问题的
话不多说,直接看上锁之后的代码


ShareDataThread.java加锁后的修改如下。

package thread;

public class ShareDataThread implements Runnable {

	private int i = 0;

	@Override
	public void run() {
		while (i < 10) {
			synchronized(this){   // 锁块
				i++;
				for (int j = 0; j < 10000000l; j++);
				System.out.println(Thread.currentThread().getName() + ": " + i);
			}
		}
	}
}


OneObjExample.java 执行类,不变

package thread;

public class OneObjExample {
	
	public static void main(String abc[]) {

		ShareDataThread s1 = new ShareDataThread();
		
		Thread t1 = new Thread(s1);
		Thread t2 = new Thread(s1);
		
		t1.start();
		t2.start();
	}
}


运行结果如下:

Thread-1: 1

Thread-1: 2

Thread-1: 3

Thread-0: 4

Thread-0: 5

Thread-1: 6

Thread-1: 7

Thread-0: 8

Thread-0: 9

Thread-0: 10

Thread-1: 11

注意:运行结果,似乎不怎么尽如人意,稍后我会继续完善的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: