码迷,mamicode.com
首页 > 编程语言 > 详细

Java-关键字之synchronized总结

时间:2015-08-30 06:37:10      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:synchronized

纸上得来终觉浅,绝知此事要躬行  --陆游    问渠那得清如许,为有源头活水来  --朱熹

在Java中,每一个对象有且仅有一个同步锁,同步锁是依赖于对象而存在。当调用某个对象的synchronized方法时,就获取了该对象的同步锁。不同线程对同步锁的访问时互斥的。

synchronized基本规则:
(一)当一个线程访问某个对象的synchronized方法或者代码块时,其他线程对此对象的synchronized方法或者代码块的访问都会被阻塞。
(二)当一个线程访问某个对象的synchronized方法或者代码块时,其他线程仍然可以访问给对象的非同步代码块。
(三)当一个线程访问某个对象的synchronized方法或者代码块时,其他线程对此对象的其他synchronized方法或者代码块的访问都会被阻塞。

基本原则(一)当一个线程访问某个对象的synchronized方法或者代码块时,其他线程对此对象的synchronized方法或者代码块的访问都会被阻塞。示例代码:
public class MyRunnable implements Runnable{
public void run()
{
synchronized (this)
{

try {
for (int i = 0; i <5; i++)
{
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"loop"+i);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class Hello {
public static void main(String []args)
{
MyRunnable run=new MyRunnable();
Thread t1=new Thread(run, "Thread1");
Thread t2=new Thread(run,"Thread2");
t1.start();
t2.start();
}
}
运行结果:
Thread1loop0
Thread1loop1
Thread1loop2
Thread1loop3
Thread1loop4
Thread2loop0
Thread2loop1
Thread2loop2
Thread2loop3
Thread2loop4
当继承Thread类时,是用synchronized时并没有影响,因为创建的是单个线程,并不会有影响。
示例:
public class MyThread extends Thread{

    public MyThread(String name)
    {
        super(name);
    }
    public void run()
    {
        synchronized (this)
        {
            for(int i=0;i<5;i++)
            {
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+"loop"+i);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}
public class Hello {
    public static void main(String []args)
    {
        MyThread myThread=new MyThread("thread1");
        MyThread mm=new MyThread("thread2");
        myThread.start();
        mm.start();
    }
}

运行结果:
thread1loop0
thread2loop0
thread1loop1
thread2loop1
thread1loop2
thread2loop2
thread1loop3
thread2loop3
thread1loop4
thread2loop4

基本原则(二):当一个线程访问某个对象的synchronized方法或者代码块时,其他线程仍然可以访问给对象的非同步代码块。示例代码:

public class Out {

public void synMethod()//同步方法
{
synchronized (this) {
for(int i=0;i<5;i++)
{
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" loop"+i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}
}
public void nosynMethod()//非同步方法
{
for(int i=0;i<5;i++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" nosynMethod"+i);
}
}

}
public class Hello {
public static void main(String []args)
{
final Out out=new Out();
//t1,t2访问的是同步块,t3访问的时非同步块
Thread t1=new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
out.synMethod();
}
}, "thread1");
Thread t2=new Thread(new Runnable() {

public void run() {
// TODO Auto-generated method stub
out.synMethod();
}
}, "thread2");
Thread t3=new Thread(new Runnable() {

public void run() {
// TODO Auto-generated method stub
out.nosynMethod();
}
}, "thread3");
t1.start();
t2.start();
t3.start();
}
}
运行结果:thread3和thread2可以并行运行,thread2和thread1就不可以,因为他们运行的由同步块修饰的函数
thread3 nosynMethod1
thread2 loop2
thread3 nosynMethod2
thread2 loop3
thread3 nosynMethod3
thread2 loop4
thread3 nosynMethod4
thread1 loop0
thread1 loop1
thread1 loop2
thread1 loop3
thread1 loop4

基本原则(三):当一个线程访问某个对象的synchronized方法或者代码块时,其他线程对此对象的其他synchronized方法或者代码块的访问都会被阻塞。示例代码:
public class Out {

public void synMethod()//同步方法
{
synchronized (this) {
for(int i=0;i<5;i++)
{
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" synMethod"+i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}
}
public void synMethod2()//非同步方法
{
synchronized (this) {
for(int i=0;i<5;i++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" Method"+i);
}
}
}
}
public class Hello {
public static void main(String []args)
{
final Out out=new Out();
//t1,t2访问的是同步块,t3访问的时非同步块
Thread t1=new Thread(new Runnable() {
public void run() {
// TODO Auto-generated method stub
out.synMethod();
}
}, "thread1");
Thread t2=new Thread(new Runnable() {

public void run() {
// TODO Auto-generated method stub
out.synMethod();
}
}, "thread2");
Thread t3=new Thread(new Runnable() {

public void run() {
// TODO Auto-generated method stub
out.synMethod2();
}
}, "thread3");
t1.start();
t2.start();
t3.start();
}
}
运行结果分析可得,都是单线程运行的,同一时间内只能使用对象的一个同步方法。
thread1 synMethod0
thread1 synMethod1
thread1 synMethod2
thread1 synMethod3
thread1 synMethod4
thread3 Method0
thread3 Method1
thread3 Method2
thread3 Method3
thread3 Method4
thread2 synMethod0
thread2 synMethod1
thread2 synMethod2
thread2 synMethod3
thread2 synMethod4

synchronized方法和synchronized代码块
synchronized方法是用synchronized修饰方法,而synchronized代码块是用synchronized修饰代码块。
synchronized方法示例:
public synchronized void foo1() 
{
System.out.println("synchronized methoed");
}
synchronized代码块示例:
public void foo2() 
{
synchronized (this)
{
System.out.println("synchronized methoed");
}
}
synchronized代码块中的this是指当前对象,也可以将this替换成其他对象。
synchronized代码块更精确的控制冲突限制访问区域,有时候效率会更高。

版权声明:知识在于分享,技术在于交流,转载时请留一个博主的链接就好

Java-关键字之synchronized总结

标签:synchronized

原文地址:http://blog.csdn.net/qq924862077/article/details/48096717

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!