正文
java同步代码段 java同步代码快
小程序:扫一扫查出行
【扫一扫了解最新限行尾号】
复制小程序
【扫一扫了解最新限行尾号】
复制小程序
Java中的同步——示例程序
前面说到了Java中的同步问题 下面通过一个小小的实例程序来演示Java中的同步方法 其中对前文提到的Counter类做了稍微的修改
public class Counter {
private int c = ;
public void increment() {
System out println( before increment c = + c);
c++;
try {
Thread sleep( );
} catch (InterruptedException e) {
e printStackTrace();
}
System out println( after increment c = + c);
}
public void decrement() {
System out println( before decrement c = + c);
c ;
try {
Thread sleep( );
} catch (InterruptedException e) {
e printStackTrace();
}
System out println( after decrement c = + c);
}
public int value() {
return c;
}
}
在上面的Counter类的实现中 分别对increment和decrement方法中增加了sleep( )的调用 这样做的目的是为了放大两个线程对同一对象的方法调用时的交错效果
下面是两个线程 在ThreadA中调用了 次increment()方法 在ThreadB中调用了 次decrement()方法
Thread
public class ThreadA implements Runnable {
private Counter c;
public ThreadA(Counter c) {
this c = c;
}
@Override
public void run() {
for (int i = ; i ; i++) {
this c increment();
}
}
}
ThreadB
public class ThreadB implements Runnable {
private Counter c;
public ThreadB(Counter c) {
this c = c;
}
@Override
public void run() {
for (int i = ; i ; i++) {
this c decrement();
}
}
}
主程序如下 其中生成了两个线程threadA和ThreadB 他们共享Counter c
public class Main {
public static void main(String[] args) {
Counter c = new Counter();
ThreadA a = new ThreadA(c);
ThreadB b = new ThreadB(c);
Thread threadA = new Thread(a);
Thread threadB = new Thread(b);
threadA start();
threadB start();
}
}
执行上面的代码 可能的结果如下
before increment c =
before decrement c =
after increment c =
before increment c =
after decrement c =
before decrement c =
after increment c =
before increment c =
after decrement c =
before decrement c =
after increment c =
before increment c =
after decrement c =
before decrement c =
after increment c =
before increment c =
after decrement c =
before decrement c =
after increment c =
before increment c =
after decrement c =
before decrement c =
after increment c =
before increment c =
after increment c =
before increment c =
after decrement c =
before decrement c =
after decrement c =
before decrement c =
after increment c =
before increment c =
after increment c =
before increment c =
after decrement c =
before decrement c =
after increment c =
after decrement c =
before decrement c =
after decrement c =
从上面的输出结果中我们不难看出出现了严重的交错现象! 在increment或者是decrement方法中输出before和after本应该是成对连续出现的 但输出结果却不是如此
将上面代码的increment()和decrement()方法用synchronized 修饰后 重新运行该程序 输出结果如下
before increment c =
after increment c =
before increment c =
after increment c =
before decrement c =
after decrement c =
before increment c =
after increment c =
before decrement c =
after decrement c =
before decrement c =
after decrement c =
before decrement c =
after decrement c =
before decrement c =
after decrement c =
before increment c =
after increment c =
before decrement c =
after decrement c =
before decrement c =
after decrement c =
before decrement c =
after decrement c =
before decrement c =
after decrement c =
before increment c =
after increment c =
before decrement c =
after decrement c =
before increment c =
after increment c =
before increment c =
after increment c =
before increment c =
after increment c =
before increment c =
after increment c =
before increment c =
after increment c =
这样输出结果和没有增加synchronized修饰符时的大不相同 单独一次的increment和decrement方法并没有出现交错的现象 只是连续 次的increment()和decrement ()有交错(这个不是synchronized能解决的问题)
至少 我们从上面的实例程序中可以看到synchronized方法的作用了
lishixinzhi/Article/program/Java/hx/201311/26369
java中的同步代码块,为什么随便放个对象,就可以锁住代码块呢?什么原理?
synchronized(这里的对象你看成一道门) {
这里是一个人进来了java同步代码段,把门反锁了
需要同步操作的代码
这里是里面的人事情做完了,出去了,门开着其java同步代码段他人可以进了
}
至于怎么锁的,这是java和jvm的规定和实现细节,作为普通程序员没必要深入那么多。
浅谈Java多线程的同步问题
多线程的同步依靠的是对象锁机制 synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问
下面以一个简单的实例来进行对比分析 实例要完成的工作非常简单 就是创建 个线程 每个线程都打印从 到 这 个数字 我们希望线程之间不会出现交叉乱序打印 而是顺序地打印
先来看第一段代码 这里我们在run()方法中加入了synchronized关键字 希望能对run方法进行互斥访问 但结果并不如我们希望那样 这是因为这里synchronized锁住的是this对象 即当前运行线程对象本身 代码中创建了 个线程 而每个线程都持有this对象的对象锁 这不能实现线程的同步
代码 package vista; class MyThread implements java lang Runnable { private int threadId;
public MyThread(int id) { this threadId = id; }
@Override public synchronized void run() { for (int i = ; i ; ++i) { System out println( Thread ID: + this threadId + : + i); } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { for (int i = ; i ; ++i) { new Thread(new MyThread(i)) start(); Thread sleep( ); } } }
从上述代码段可以得知 要想实现线程的同步 则这些线程必须去竞争一个唯一的共享的对象锁
基于这种思想 我们将第一段代码修改如下所示 在创建启动线程之前 先创建一个线程之间竞争使用的Object对象 然后将这个Object对象的引用传递给每一个线程对象的lock成员变量 这样一来 每个线程的lock成员都指向同一个Object对象 我们在run方法中 对lock对象使用synchronzied块进行局部封锁 这样就可以让线程去竞争这个唯一的共享的对象锁 从而实现同步
代码 package vista;
class MyThread implements java lang Runnable { private int threadId; private Object lock;
public MyThread(int id Object obj) { this threadId = id; this lock = obj; }
@Override public void run() { synchronized (lock) { for (int i = ; i ; ++i) { System out println( Thread ID: + this threadId + : + i); } } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { Object obj = new Object(); for (int i = ; i ; ++i) { new Thread(new MyThread(i obj)) start(); Thread sleep( ); } } }
从第二段代码可知 同步的关键是多个线程对象竞争同一个共享资源即可 上面的代码中是通过外部创建共享资源 然后传递到线程中来实现 我们也可以利用类成员变量被所有类的实例所共享这一特性 因此可以将lock用静态成员对象来实现 代码如下所示
代码 package vista;
class MyThread implements java lang Runnable { private int threadId; private static Object lock = new Object();
public MyThread(int id) { this threadId = id; }
@Override public void run() { synchronized (lock) { for (int i = ; i ; ++i) { System out println( Thread ID: + this threadId + : + i); } } } }
public class ThreadDemo { /** * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { for (int i = ; i ; ++i) { new Thread(new MyThread(i)) start(); Thread sleep( ); } } }
再来看第一段代码 实例方法中加入sychronized关键字封锁的是this对象本身 而在静态方法中加入sychronized关键字封锁的就是类本身 静态方法是所有类实例对象所共享的 因此线程对象在访问此静态方法时是互斥访问的 从而可以实现线程的同步 代码如下所示
代码 package vista;
class MyThread implements java lang Runnable { private int threadId;
public MyThread(int id) { this threadId = id; }
@Override public void run() { taskHandler(this threadId); }
private static synchronized void taskHandler(int threadId) { for (int i = ; i ; ++i) { System out println( Thread ID: + threadId + : + i); } } }
lishixinzhi/Article/program/Java/gj/201311/27441
java同步代码段的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java同步代码快、java同步代码段的信息别忘了在本站进行查找喔。