synchronized同步方法\块只有一个线程执行\运行

最近复习Java多线程的时候, 发现一个问题, 使用synchronized锁时, CPU从头到尾只调度一个线程去执行, 其他两个线程似乎没有什么用:

package com.gyb.thread;

public class SynDemo01 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 初始化线程类
		Web12306 web = new Web12306();
		// 代理
		Thread t1 = new Thread(web, "路人甲");
		Thread t2 = new Thread(web, "黄牛已");
		Thread t3 = new Thread(web, "攻城师");
		// 启动线程
		t1.start();
		t2.start();
		t3.start();
	}
}

/**
 * 线程安全的类
 * 
 * @author Administrator
 *
 */
class Web12306 implements Runnable {
	private Integer num = 10;
	private boolean flag = true;

	@Override
	public void run() {
		while (flag) {
			test2();
		}
	}

	// 线程安全 锁定正确
	public synchronized void test2() {
		if (num <= 0) {
			flag = false; // 跳出循环
			return ;
		}
		try {
			// 模拟 延时
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName() + "抢到了" + num--);
	}
}

输出结果:
路人甲抢到了10
路人甲抢到了9
路人甲抢到了8
路人甲抢到了7
路人甲抢到了6
路人甲抢到了5
路人甲抢到了4
路人甲抢到了3
路人甲抢到了2
路人甲抢到了1

测试与解决:

  • 方法① 将num由10改为1000, 输出结果, 可以看到8700多的时候CPU才调度的名为’黄牛’的线程:
    在这里插入图片描述
    方法② 在synchronized同步方法或同步块之前再增加一个sleep方法:
    在这里插入图片描述
    结果与猜想:

  • 这个跟CPU性能有关, 完全一致的代码在我的电脑和公司的电脑上, 发现CPU对线程调度与执行速度不一致,

  • 上面的方法① 实际测试过,性能好的CPU需要大量增加线程循环执行次数, 我的机器上是10000次), 才能看到其他线程的执行,
    而公司的电脑只要循环10次, 就能看到别的线程执行了(说明好的CPU单个线程更牛X?)

  • 上面的方法② 当sleep在synchronized同步方法或同步块之外的时候,三个线程都有执行, 是因为sleep方法会给其他线程运行的机会,而不管其他线程的优先级, (但在synchronized同步方法里的sleep, 由于被锁住所以没有优先级之说, 也就是说synchronized同步方法里的sleep失效了, 这是我的猜想)

  • 想看到线程具体的执行过程,可以打开JDK bin目录下的jvisualvm.exe 监视JavaJVM的状态,如图:
    在这里插入图片描述

有不足之处请指出, 转载请注明出处, 谢谢~!

  • 32
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值