java-线程同步机制(可靠版):
所谓的可靠其实就是在原版之上再加一个互斥锁。锁顾名思义就意味着先把一个任务锁起来,让他执行完,然后拷贝一份去完成后面的工作。这样一来便可以保证数据的完成性,实现真正的数据同步。废话不多说,直接看代码:
package com.etc.xiancheng.xctongbujizhi2;
/**
* 使用锁复制 :synchronized() 操作保证数据同步
*
* 注:因为不巧当的使用锁,导致线程锁死,deadlock
*/
public class Key {
private byte[] data = new byte[16];
public Key() {
update((byte) 0);
}
// 更新密钥
public void update(byte seed) {
// 加入锁:
synchronized (this) {
for (int i = 0; i < data.length; i++) {
data[i] = seed;
}
}
}
// 获取密钥(拷贝一份数据,作为下一步操作,保证了原数据的安全)
public byte[] get() {
byte[] copy = new byte[data.length];
// 加入锁:
synchronized (this) {
// 复制一份传过去
System.arraycopy(data, 0, copy, 0, data.length);
return copy;
}
}
}
package com.etc.xiancheng.xctongbujizhi2;
/**
* 实现多线程对同一个对像的同步访问,且一个读有一个写,容易发生不同步现象
* 则需要线程同步,引入互斥锁的概念:
* 1.若别的线程正持有该锁,则本线程阻塞等待。
* 2.若此锁空闲,则本线程持有锁(locked),进入大括执行,完毕之后释放锁。
* <p>
* 线程同步:就是让两个线程步调一致,有序地访问的同一对象。
*/
public class KeyTest {
// 定期更新密钥
private class KeyUpdater extends Thread {
private Key key;
public KeyUpdater(Key k) {
this.key = k;
}
public void run() {
byte seed = 0;
while (true) {
// 更新密钥,每次加1
seed++;
if (seed > 100) seed = 0;
key.update(seed);
try {
Thread.sleep(5);
} catch (InterruptedException e) {
}
}
}
}
// 定期读取密钥
private class KeyPrinter extends Thread {
private Key key;
public KeyPrinter(Key k) {
this.key = k;
}
public void run() {
byte seed = 0;
while (true) {
// 得到key 值并打印
byte[] data = key.get();
for (int i = 0; i < data.length; i++)
System.out.print(String.format("%02X", data[i]));
System.out.print("\n");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
}
}
}
}
public void test() {
Key key = new Key();
KeyUpdater t1 = new KeyUpdater(key);
KeyPrinter t2 = new KeyPrinter(key);
t1.start();
t2.start();
}
public static void main(String[] args) {
KeyTest k1 = new KeyTest();
k1.test();
}
}