并发编程1(并发编程的使用目的以及带来的问题)

并发编程

  • 为什么要使用并发编程?
  • 并发编程所带来的问题,以及如何避免?

并发编程是为了让程序运行的更快

  使用并发编程的目的是加快程序的运行速度,但同样的使用并发编程会带来新的问题。上下文切换问题、死锁问题

上下文切换

:上下文切换是什么,导致产生上下文切换问题的原因是什么呢?
:对于单核处理器的计算机而言,CPU是通过为多线程分配CPU时间片来实现多线程的,多个线程共同抢占CPU分配的有限时间片,时间片抢占执行完后,返回就绪状态,或者程序执行完毕。但是在当前任务抢占完并执行完一个时间片后,切换前会保留上一个任务的状态,方便下一次切换回加载这个任务。所以,任务从保存到加载的过程就是一次上下文的切换
 可想而知,这个保留当前任务,并再次加载任务的过程就会造成不必要的时间浪费。所以,无限制的增加线程并不能一直增加程序的执行效率。
如何减少上下文的切换?

  • 无锁并发编程。多线程竞争锁的时候,会引起上下文切换,所以多线程处理数据的时候,可以用一些办法来避免使用锁。
  • CAS算法(Compare and Swap)。Java的Atomic包使用CAS算法来更新数据,而不需要加锁。
  • 使用最少线程。避免不需要的线程。
  • 协程。在单线程里实现多任务的调度算法,并在单线程里维持多个任务的切换。
死锁

  并发编程过程中,由于多个线程间,共同抢占对方需要而又没有及时释放掉的资源,很容易导致死锁的情况发生。
 面试的时候偶尔也会遇到,让手写一个死锁的情况。

public class DeadLockDemo {
	privat static String A = "A";
	privat static String B = "B";
  	
  	public static void main(String[] args) {
  		Thread t1 = new Thread(new Runnable()) {
  			@Override
  			public void run() {
  				sychronized(A) {
  					try {
  						Thread.currentThread().sleep(2000);
  					}catch (InterruptedException e) {
  						e.printStackTrace();
  					}
  					sychronized(B) {
  						System.out.println("1");
  					}
  				}
  			}
  		});
  		Thread t2 = new Thread(new Runnable()) {
  			@Override
  			public void run() {
  				sychronized(B) {
  					sychronized(A) {
  						System.out.println("2");
  					}
  				}
  			}
  		});
  		t1.start();
  		t2.start();
  	}
}

如何避免死锁呢?

  • 避免一个线程同时获取多个锁。
  • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
  • 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。
  • 对于数据库锁,加锁和解锁必须在一个数据库连接内,否则会出现解锁失败。
发布了16 篇原创文章 · 获赞 1 · 访问量 867

猜你喜欢

转载自blog.csdn.net/nisemono_ct/article/details/103865321