synchronize和volatile关键字

       Java语言是支持多线程的,为了解决线程并发的问题,在语言内部引入了 同步块(synchronized) 和 volatile 关键字机制。

synchronized

       在多线程访问的时候,同一时刻只能有一个线程能够用访问synchronized修饰的代码块。
举例

/*
 * 创建两个线程,使用一个公共资源count,每一个线程在执行run方法是会输出名称和count的值,因为java线程具有随机性,因此输出的内容顺序会乱
 * 输出结果:
 * thread1:0
 * thread1:2
 * thread1:3
 * thread1:4
 * thread1:5
 * thread2:1
 * thread2:6
 * thread2:7
 * thread2:8
 * thread2:9
 */
public class Synchronized implements Runnable{
	//共享资源变量
    int count = 0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	  Synchronized synchronizedTest = new Synchronized();
      Thread thread1 = new Thread(synchronizedTest,"thread1");
      Thread thread2 = new Thread(synchronizedTest, "thread2");
      thread1.start();
      thread2.start();
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+":"+count++);
        }
	}
}

       使用了synchronized关键字修饰run方法后,输出结果就是正常的,保证同一时间内就一个线程执行。

/*输出结果:
 *thread1:0
 *thread1:1
 *thread1:2
 *thread1:3
 *thread1:4
 *thread2:5
 *thread2:6
 *thread2:7
 *thread2:8
 *thread2:9
 */
public synchronized void run() {
		// TODO Auto-generated method stub
		for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+":"+count++);
        }
	}

volatile

       用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值(都强制从主内存中取值,而不是自己的工作内存),即保证数据的一致性。

举例

/*
 * 该程序首先创建一个Volatile类对象,然后执行run函数,之后线程休眠2秒,修改标志位,查看最后能否跳出while循环并输出
 * 结果是无法跳出循环,表明volatileTest.flag = true;不起作用
 */
public class Volatile extends Thread{
	boolean flag = false;
	int i = 0;
	
	public void run() {
		while (!flag) {
			i++;
		}
	}

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		Volatile volatileTest = new Volatile();
		volatileTest.run();
		Thread.sleep(2000);
		volatileTest.flag = true;
		System.out.println("stop " + volatileTest.i);
	}
}

上面程序无法跳出循环的原因是执行的线程为volatileTest,但是标志位是在主线程(main)中修改,因此在volatileTest线程中没有更新。
使用volatile关键字修饰flag变量后,就可以跳出循环,表示赋值成果(每次都从主内存取值)。

volatile boolean flag = false;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值