经过三天的理解,终于对synchronized有些了解,废话不多说:
首先创建一个对象锁 Object Lock = new Object();
设置同步代码块 synchronized(Lock)
1:Wait():
Lock.Wait() 用意:立即将当前线程“睡眠”,也就是使当前线程阻塞,是自己处于等待获取对象锁的状态,释放锁 Lock,让其他等待使用Lock线程中的一个线
程获取对象锁Lock(具体是哪个,现在的我们难控制,看电脑心情)。
如果一个线程调用了某个对象的wait方法,但是后续并没有其他线程调用该对象的notify或者notifyAll方法,则该线程将会永远等下去…
2:Notify()/NotifyAll:
Lock.Notify()/Lock.NotifyAll() 用意:通知一个/所有正在等待获取该对象锁的线程,自己将要over,要让出王位,各位做好准备抢夺王位。但他不是像Wait()一样,
一下就挂掉了,他在昭告天下以后,要让同步代码块执行完后他才释放
下面我来说明一下 wait() 与 notify()的不同:
有人会问,他们两个都是释放对象锁让下一个线程运行,为什么不合并。我想说的是他们两个自有他们存在的价值。
不同: wait():立即睡眠 notify():等待代码块运行完再结束
wait():等待激活 notify():不会等待激活
wait():不会唤醒其他线程 notify():唤醒其他线程
太多了 ,就例举出这几条。
以一个例子,来解释:
对了,记住一句话:如果一个对象之前没有调用wait方法,那么调用notify方法是没有反应的。因为根本没有在等待该对象锁的线程,notify()就不能通知到
public class MainActivity extends Activity {
Handler t2;
calThread t1;
class calThread extends Thread
{
Handler handler;
//创建对象锁
private final Object mSync = new Object();
@Override
public void run() {
System.out.println("1");
Looper.prepare();
synchronized (mSync) {
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
System.out.println("2");
if(msg.what == 0x123)
{
System.out.println("11");
}
}
};
mSync.notify();
}
Looper.loop();
}
public Handler getHandler() {
System.out.println("3");
synchronized (mSync) {
if (handler == null) {
try {
System.out.println("4");
mSync.wait();// 主线程睡眠等待唤醒释放对象锁
//主线程再次运行时
System.out.println("8");
} catch (InterruptedException e) {
}
}
return handler;
}
}
public void exit() {
System.out.println("exit");
getHandler().post(new Runnable(){
public void run() {
System.out.println("run");
Looper.myLooper().quit();
}});
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = (Button) findViewById(R.id.bt);
t1 = new calThread();
System.out.println("start1");
t1.start();
System.out.println("start0");
t2 = new Handler()
{
@Override
public void handleMessage(Message msg) {
System.out.println("7");
if (msg.what == 0x124)
{
System.out.println("22");
}
}
};
t1.getHandler().sendEmptyMessage(0x123);
System.out.println("6");
}
}
我来解析一下代码的运行轨迹:
主线程MainThread()运行产生“start1”,"start0","3","4" ---->getHandler()函数中mSync.wait()使主线程睡眠等待唤醒释放对象锁------>t1线程获取对象锁run()函数开始 “1”
------>mSync.notify()开始唤醒主线程(handleMessage函数是要等主线程发生消息才会运行)------->开始主线程睡眠后的代码 “8”——>
sendEmptyMessage运行后 “2”,“11”
总的运行结果就是 “start1”,"start0","3","4", “1”, “8” , “2”,“11”
就到这里 好的连接我的博客里有
如有错误请及时点出!!!!!