MySQL Replication 线程
- - CSDN博客推荐文章Replication 线程. Mysql 的Replication 是一个异步的复制过程,从一个Mysql instace(我们称之为Master)复制到另一个Mysql instance(我们称之Slave). 在Master 与Slave 之间的实现整个复制过程主. 要由三个线程来完成,其中两个线程(Sql 线程和IO 线程)在Slave 端,另外一个线程(IO 线程)在Master 端.
以服务器模式运行下面的Java程序: ( 默认为client模式) (本机使用的是Oracle的Hotspot VM)
java -server StopThread
import java.util.concurrent.TimeUnit; // Broken! - How long would you expect this program to run ? public class StopThread { private static boolean stopRequested; // value: false public static void main(String... args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { int i = 0; while(!stopRequested) i++; } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; } }
这个例子有两个线程,一个是main线程,另一个是在main线程里启动的backgroundThread线程,这两个线程共享一个类型为boolean的stopRequested。理论上如果main线程将stopRequested变量设置为true时,backgroundThread线程会跳出循环然后结束,接着JVM也终止。但是在我的机子上(Intel i5 M460),它一直处于运行中,并不会在1秒中后停止运行。
原因要归咎于Java语言规范(JLS)中的内存模型(Memory Model)。它规定了一个线程所做的变化何时以及如何变成对其它线程可见(可见性)。因此我们不知道何时后台线程能够“看到”main线程对stopRequested的值所做的改变。一个简洁,性能好的方案是对共享变量添加volatile关键字。volatile保证任何一个线程在读取该域的时候都能“看到”最近刚刚被写入的值。
修改后的代码:
import java.util.concurrent.TimeUnit; // Broken! - How long would you expect this program to run ? public class StopThread { private static boolean volatile stopRequested; // value: false public static void main(String... args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { int i = 0; while(!stopRequested) i++; } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); stopRequested = true; } }
以服务器模式运行后会在1秒左右后自动停止VM。
除了使用关键字volatile,还可以使用synchronized。同步机制除了能够实现线程之间的互斥之外,还能实现线程间的通信(即可以实现可见性)。
import java.util.concurrent.TimeUnit; // Broken! - How long would you expect this program to run ? public class StopThread { private static boolean stopRequested; // value: false public static synchronized void requestStop() { stopRequested = true; } public static synchronized boolean stopRequested() { return stopRequested; } public static void main(String... args) throws InterruptedException { Thread backgroundThread = new Thread(new Runnable() { @Override public void run() { int i = 0; while(!stopRequested()) i++; } }); backgroundThread.start(); TimeUnit.SECONDS.sleep(1); requestStop(); } }
此时可以且应该取消volatile关键字,因为synchronized关键字也能实现可见性。
另外需要注意的是除了同步写操作之外,还应该同步读操作。如果读和写操作没有都被同步,同步就不会起作用。