并发的介绍

为什么要学习线程,因为我们可以把复杂、异步的代码转化为更简单、更直观的代码,从而简化复杂系统的开发。

线程的发展

在这里插入图片描述

多进程/多线程发展优势
  • 资源利用
    当程序需要等待输入输出的时候。等待时候可以让系统做一些有意义的其他事情,提供效率。
  • 公平
    多个用户或多个程序拥有平等的优先级,他们可以通过时间片方式来共享计算机。这把串行方式一个程序结束后,另外一个程序开始更加公平。
  • 方便
    编写一个单独执行的任务并进行必要的相互协调比编写一个程序来执行多个任务的逻辑更加容易,且更容易让人接受。
线程的风险

返回序列的方法

public class UnsafeSequence {
	private int value;
	 
    //返回一个唯一的数值
    public int getNext(){
        return value++;
    }

}

封装线程

public class UnsafeSequenceRunnable implements Runnable {
	
	private UnsafeSequence sequence;
	
	public UnsafeSequenceRunnable(UnsafeSequence sequence) {
		this.sequence = sequence;
	}

	@Override
	public void run() {
		for (int i = 0; i < 10000; i++) {
			System.out.println(String.format("当前线程:%s,数字为:%s", Thread.currentThread().getName(), sequence.getNext()));
		}
		
	}

}

测试结果发现。值少1

/**
 * 测试结果
 * 
 * 当前线程:pool-1-thread-4,数字为:99996
 * 当前线程:pool-1-thread-4,数字为:99997
 * 当前线程:pool-1-thread-4,数字为:99998
 */
public class UnsafeSequenceTest {

	public static void main(String[] args) {
		ExecutorService executorService = Executors.newCachedThreadPool();
		UnsafeSequence sequence = new UnsafeSequence();
		
		for (int i = 0; i < 10; i++) {
			executorService.execute(new UnsafeSequenceRunnable(sequence));
		}

		executorService.shutdown();
	}

}

在这里插入图片描述

三个步骤,有可能被抵消了

优化改造,关键方法加锁

public class SafeSequence {
	private int value;
	 
    //返回一个唯一的数值
    public synchronized int getNext(){
        return value++;
    }

}

其他

多线程的风险

  • 死锁
  • 上下文切换的代价

对于多个线程访问同一个变量,可解决问题的办法

  • 不要跨线程共享变量
  • 使用状态变量为不可修改
  • 在任何情况下访问状态变量的时候使用同步
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值