java 多线程 关键字_Java多线程的几个常用关键字

本文详细探讨了Java中的synchronized和volatile关键字。同步(synchronized)用于控制共享资源的访问,防止脏读,而异步(asynchronized)则意味着线程独立执行不受约束。通过代码示例展示了synchronized如何保证线程同步,以及volatile如何提供可见性但不保证原子性。此外,还对比了volatile与synchronized在线程安全性方面的差异。
摘要由CSDN通过智能技术生成

一、同步(synchronized)和异步(asynchronized)

1、同步(synchronized)简单说可以理解为共享的意思,如果资源不是共享的,就没必要进行同步。设置共享资源为同步的话,可以避免一些脏读情况。

2、异步(asynchronized)简单说可以理解为独立不受到其他任何制约。

举个例子:

线程1调用了带有synchronized关键字的方法methodA,线程2调用了异步方法methodB,出现的现象是同时控制台输出 t1,t2。

packagecom.ietree.multithread.sync;/*** 多线程之对象同步锁和异步锁Demo

*

*@authorietree*/

public classSynAndAsynDemo {public static voidmain(String[] args) {final SynAndAsynDemo mo = newSynAndAsynDemo();

Thread t1= new Thread(newRunnable() {

@Overridepublic voidrun() {

mo.methodA();

}

},"t1");

Thread t2= new Thread(newRunnable() {

@Overridepublic voidrun() {

mo.methodB();

}

},"t2");

t1.start();

t2.start();

}//方法A

public synchronized voidmethodA(){try{

System.out.println(Thread.currentThread().getName());//休眠4秒

Thread.sleep(4000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}//方法B

public voidmethodB(){

System.out.println(Thread.currentThread().getName());

}

}

线程1调用了带有synchronized关键字的方法methodA,线程2调用了带有synchronized关键字的方法methodB,出现的现象是首先输出t1,等待4秒之后再输出t2。

packagecom.ietree.multithread.sync;/*** 多线程之对象同步锁和异步锁Demo

*

*@authorietree*/

public classSynAndAsynDemo {public static voidmain(String[] args) {final SynAndAsynDemo mo = newSynAndAsynDemo();

Thread t1= new Thread(newRunnable() {

@Overridepublic voidrun() {

mo.methodA();

}

},"t1");

Thread t2= new Thread(newRunnable() {

@Overridepublic voidrun() {

mo.methodB();

}

},"t2");

t1.start();

t2.start();

}//方法A

public synchronized voidmethodA(){try{

System.out.println(Thread.currentThread().getName());//休眠4秒

Thread.sleep(4000);

}catch(InterruptedException e) {

e.printStackTrace();

}

}//方法B

public synchronized voidmethodB(){

System.out.println(Thread.currentThread().getName());

}

}

结论:

在第一段代码中t1线程先持有object对象的Lock锁,t2线程可以以异步的方式调用对象中的非synchronized修饰的方法,所以同时输出;

在第二段代码中t1线程先持有object对象的Lock锁,t2线程如果在这个时候调用对象中的同步(synchronized)方法则需等待,也就是同步。

二、volatile

作用:volatile关键字的作用是:使变量在多个线程间可见(具有可见性),但是仅靠volatile是不能保证线程的安全性,volatile关键字不具备synchronized关键字的原子性。

Demo1:

packagecom.ietree.multithread.sync;public class RunThread extendsThread {//volatile

private boolean isRunning = true;private void setRunning(booleanisRunning) {this.isRunning =isRunning;

}public voidrun() {

System.out.println("进入run方法..");int i = 0;while (isRunning == true) {//..

}

System.out.println("线程停止");

}public static void main(String[] args) throwsInterruptedException {

RunThread rt= newRunThread();

rt.start();

Thread.sleep(1000);

rt.setRunning(false);

System.out.println("isRunning的值已经被设置了false");

}

}

程序输出:

进入run方法..

isRunning的值已经被设置了false

之后进入死循环

Demo2:

packagecom.ietree.multithread.sync;public class RunThread extendsThread {//volatile

private volatile boolean isRunning = true;private void setRunning(booleanisRunning) {this.isRunning =isRunning;

}public voidrun() {

System.out.println("进入run方法..");int i = 0;while (isRunning == true) {//..

}

System.out.println("线程停止");

}public static void main(String[] args) throwsInterruptedException {

RunThread rt= newRunThread();

rt.start();

Thread.sleep(1000);

rt.setRunning(false);

System.out.println("isRunning的值已经被设置了false");

}

}

程序输出:

isRunning的值已经被设置了false

线程停止

总结:当多个线程之间需要根据某个条件确定 哪个线程可以执行时,要确保这个条件在 线程之间是可见的。因此,可以用volatile修饰。

volatile 与 synchronized 的比较:

①volatile轻量级,只能修饰变量。synchronized重量级,还可修饰方法

②volatile只能保证数据的可见性,不能用来同步,因为多个线程并发访问volatile修饰的变量不会阻塞。

synchronized不仅保证可见性,而且还保证原子性,因为,只有获得了锁的线程才能进入临界区,从而保证临界区中的所有语句都全部执行。多个线程争抢synchronized锁对象时,会出现阻塞。

线程安全性包括两个方面,①可见性。②原子性。

从上面自增的例子中可以看出:仅仅使用volatile并不能保证线程安全性。而synchronized则可实现线程的安全性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值