java线程的同步
2015-10-11 14:30
295 查看
线程的使用,让程序的执行更为灵活,给我们的生活提供的更多的方便,尤其是服务器,已经游戏中使用的大量多线程,但是任何东西都是有两面性的,由于我们不可以对线程的执行几率进行控制,所以有存在很多的安全问题。那么怎么才能使线程同步呢
java提供的机制是使用synchronized关键字,背后使用了封锁来实现资源的互斥访问
synchronized的第一种用法,同步代码块
这是一个实现简单的卖票程序,有两个线程会对其操作,那么就有问题了,就是一个线程在执行操作到一半时,cpu被抢了,另一个线程有来执行,就很可能出现卖同一张票,或者卖不存在的票,那么我们可以用同步代码块让对票操作的相代码是锁起来,只要一个线程没有执行完锁里边的代码,就不会释放多代码块的所有权,这样即使中间断开后,另一个线程来执行,发现锁还没有解开,就没办法去执行。
第二种用法 同步方法
public synchronized void produce()
{
if(!flag)
{
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在生产第"+(++product)+"个");
flag = true;
if(product==1)
{
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
这里的锁定的对象,是this也就是说,谁调用我就锁定谁。如果是静态方法,那么锁定的类的实例,在类加载的使用就锁定这个类的实例
如果要实现同步关键就看锁定的对象是不是同一个
java提供的机制是使用synchronized关键字,背后使用了封锁来实现资源的互斥访问
synchronized的第一种用法,同步代码块
</pre><pre name="code" class="java">package cn.java.thread; class Ticket2 extends Thread { public static int ticket =1000; public void run() { while(true) { synchronized ("")/*设置一个锁,只有一个线程可以用这个锁,在这个锁的范围类,只有把这个锁里边的代码执行完毕,才会自动释放,其他线程才可以来抢占这个锁,若果这个锁被 一个线程占用,并且其他还没有释放这个锁,其他线程就没法来占用,里边的参数 object可以为如何一个对象,“”也是一个对象,并放是放在数据区 的,所以只有一个,所以new出实例时只会创建一个,既两个线程锁定的对象是同一个 */ { try { Thread.sleep(1000); } catch(Exception e) { } if(ticket>0) { System.out.println(Thread.currentThread().getName()+ticket--+"票"); } else break; } } } } public class Test_synchro_2 { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Ticket2 bb =new Ticket2(); Ticket2 cc =new Ticket2(); bb.setName("窗口1卖出第:"); cc.setName("窗口2卖出第:"); bb.start(); cc.start(); } }
这是一个实现简单的卖票程序,有两个线程会对其操作,那么就有问题了,就是一个线程在执行操作到一半时,cpu被抢了,另一个线程有来执行,就很可能出现卖同一张票,或者卖不存在的票,那么我们可以用同步代码块让对票操作的相代码是锁起来,只要一个线程没有执行完锁里边的代码,就不会释放多代码块的所有权,这样即使中间断开后,另一个线程来执行,发现锁还没有解开,就没办法去执行。
第二种用法 同步方法
public synchronized void produce()
{
if(!flag)
{
try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在生产第"+(++product)+"个");
flag = true;
if(product==1)
{
this.notify();
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
这里的锁定的对象,是this也就是说,谁调用我就锁定谁。如果是静态方法,那么锁定的类的实例,在类加载的使用就锁定这个类的实例
如果要实现同步关键就看锁定的对象是不是同一个
相关文章推荐
- Eclipse快捷键大全(转载)
- Java的初始化与清理
- Hub Player播放器 Java mp3播放器
- Eclipse 中常用的快捷键
- Windows 7下JDK与Ant的安装和环境变量配置
- NumberFormat类与DecimalFormat类
- 利用数组实现大数的阶乘
- java 集成开发环境选择对比
- Java开发环境的配置(Windows)
- Java形参个数可变的方法
- Spring Framework 4.2 中的新功能和增强功能
- Spring-----<context:annotation-config/>
- Java加密解密技术系列之RSA
- NetBeans项目中数据库驱动的设置
- Java基础知识强化之IO流笔记45:IO流练习之 把集合中的数据存储到文本文件案例
- You must restart adb and Eclipse的问题解决
- Java加密解密技术系列之DES
- Java加密解密技术系列之HMAC
- Myeclipse学习总结(1)——Myeclipse优化配置
- Myeclipse学习总结(1)——Myeclipse优化配置