public class volatileTest {
/*
将代码改成如下,再执行:
static volatile ArrayList<Integer> list = new ArrayList<Integer>();
线程不再死循环,因为读取list.size会触发线程刷新工作内存,可以看到,即使b、i、
str没有设置成volatile变量,仍然会一起刷新过来。
用volatile修饰b、i、str、list任何一个都能起到刷新工作内存的效果。
*/
static boolean b = false;
static int i =1;
static String str ="1";
static ArrayList<Integer> list = new ArrayList<Integer>();
public static void main(String[] arg) throws Exception {
Thread t = new Thread(new Runnable() {
public void run() {
printf(String.format("[%s] _start_ b=%s i=%d str=%s",
Thread.currentThread().getName(), b,i,str));
/*等待list 、b 、I、 str中任何一个变
化,都会跳出这个循环*/
while(list.size() == 0 && !b && i==1 && str.equals("1"));
printf (String.format("[%s] _end_ b=%s i=%d str=%s",
Thread.currentThread().getName(), b,i,str));
}
});
t.start();
Thread.sleep(1000);
/*改变他们的值*/
list.add(new Integer(1));
b=true;i=2;str="2";
printf (String.format("main end b=%s i=%d str=%s", b,i,str));
}
}
运行结果:线程进入死循环,因为线程不会主动去读取主内存中的值。
JMM 对 synchronized 也实现了同样的语义保证:
获取锁:将线程工作内存区域中的共享变量设置成无效,必须从主内存重新获取。
释放锁:将工作内存中的数据刷新到主内存。
public class volatileTest {
static boolean b = false;
static int i =1;
static String str ="1";
static ArrayList<Integer> list = new ArrayList<Integer>();
public static void main(String[] arg) throws Exception {
Thread t = new Thread(new Runnable() {
public void run() {
printf(String.format("[%s] _start_ b=%s i=%d str=%s",
Thread.currentThread().getName(), b,i,str));
while(list.size() == 0 && !b && i==1 && str.equals("1"))
{
// b 、i、str、list 虽然都没有设置成 volatile,这里的 synchronized 具有保持工作内存与主内存一致性的效果。
synchronized (this){}
/*
隐藏的锁
System.out.println()
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
*/
System.out.println("")
}
printf(String.format("[%s] _end_ b=%s i=%d str=%s",
Thread.currentThread().getName(), b,i,str));
}
});
t.start();
Thread.sleep(1000);
list.add(new Integer(1));
b=true;i=2;str="2";
printf(String.format("main end b=%s i=%d str=%s", b,i,str));
}
}
线程等待-恢复,恢复时会重新加载主内存:
线程休眠
Thread.currentThread().sleep(1);
线程暂停
Thread.currentThread().suspend();
可重入锁
reentrantLock.lock();
reentrantLock.unlock();
readWritelock.readLock().lock(); //读锁
readWritelock.readLock().unlock();
readWritelock.writeLock().lock();//写锁
readWritelock.writeLock().unlock();
循环屏障等待
try{barrier.await();}catch (Exception e){}
交换器等待交换
try{exchanger.exchange(1);}catch (Exception e){}
语义锁
synchronized (lockObject) {
try { lockObject.wait();}catch (Exception e){}
}
LockSupport 的阻塞-恢复:
LockSupport.parkNanos(1);
LockSupport.park();
CountDownLatch 的 await 等待-恢复:
try{ latch.await(); }catch (Exception e){ }
public class volatileTest {
static boolean b = false;
static int i =1;
static String str ="1";
static ArrayList<Integer> list = new ArrayList<Integer>();
public static void main(String[] arg) throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
final CyclicBarrier barrier = new CyclicBarrier(2);
final Exchanger exchanger = new Exchanger();
final Object lockObject = new Object();
Thread t = new Thread(new Runnable() {
public void run() {
printf(String.format("[%s] _start_ b=%s i=%d str=%s",
Thread.currentThread().getName(), b,i,str));
while(list.size() == 0 && !b && i==1 && str.equals("1"))
{
try{Thread.sleep(1);}catch (Exception e){}
}
printf(String.format("[%s] _end_ b=%s i=%d str=%s",
Thread.currentThread().getName(), b,i,str));
}
});
t.start();Thread.sleep(1000);
list.add(new Integer(1));b=true;i=2;str="2";
printf(String.format("main end b=%s i=%d str=%s", b,i,str));
}
}
