您的位置 首页 java

Java的线程同步

一般来说,每个线程只有在确保资源不能被改变或者自身对资源具有独占权时,这个资源才是安全的. Java 提供了同步机制来保证线程能安全的访问资源。

1.同步

通过在方法上加入 synchronized 关键字,可以保证方法在一个线程调用时,其他线程不能调用,即线程在这个方法执行期间取得了对这个方法的独占权。

public synchronized String test(){

//do some thing

}

2.同步块

与同步类似,只是可以更加灵活控制需要同步的范围。

public String test(){

synchronized( lock ){

//do some thing

}

}

需要注意的是,同步块需要一个”锁”,谁先获得了这个锁,谁就先进入这个”门”内,其他线程只能在门外等待,直到先进入者出来,锁自动释放,其他线程再去竞争。

仍然以之前的示例来验证。

public static void main(String[] arg){

Thread thread1=new Thread(new Runnable() {

@Override

public void run() {

print(“1”);

}

});

Thread thread2=new Thread(new Runnable() {

@Override

public void run() {

print(“2”);

}

});

thread1. start ();

thread2.start();

}

public static synchronized void print(String msg ){

int count=0;

while(count<10){

System.out.print(msg);

count++;

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

运行后,我们看到,两个线程有序执行了。

换成同步块,结果一致。

public static void print(String msg){

synchronized(System.out){

int count=0;

while(count<10){

System.out.print(msg);

count++;

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

然而,对于同步问题,仅仅通过synchronized并不是一劳永逸的解决方案。首先,Java 虚拟机 为了保证这种机制比然需要进行一系列的如加锁等措施,它必然导致程序性能的下降,尤其是在早期的虚拟机中,这个问题相当严重,最新的Java虚拟机一直在同步处理上改进,性能问题可能不再是问题。其次,同步本身还会大大增加 死锁 的机会,如果两个线程都在等待一个被对方获取了的资源才能正常工作,那么两个线程将一直等待。

事实上,也还有很多技术或思路可以完全避免同步。使用 局部变量 代替字段;使用简单类型的参数和字段;String是 线程安全 的,因为一旦创建它的值就不能被改变;创建不可变对象,它们的值只在 构造函数 中改变,不提供写的方法,构造函数一般不需要担心线程安全问题;使用线程本地变量 ThreadLocal ,这是一种将数据在线程内共享的技术,就是每个线程都会得到一份数据的副本。在实际开发中,需要结合具体的业务需求去分析 。

文章来源:智云一二三科技

文章标题:Java的线程同步

文章地址:https://www.zhihuclub.com/186328.shtml

关于作者: 智云科技

热门文章

网站地图