Java基础(三十八)-线程相关

线程的同步与死锁

1:同步问题的引出

class MyThread implements Runnable {
	private int ticket = 10 ; // 总票数为10张
	@Override
	public void run() {
		while (true) {
			if (this.ticket > 0) {
				System.out.println(Thread.currentThread().getName() + "卖票,ticket = " + this.ticket --);
			} else {
				System.out.println("***** 票已经卖光了 *****");
				break ;
			}
		}
	}
}
public class Test { 
	public static void main(String[] args) throws Exception {
		MyThread mt = new MyThread() ;
		new Thread(mt,"票贩子A").start();
		new Thread(mt,"票贩子B").start();
		new Thread(mt,"票贩子C").start();
	}
}
//运行结果
票贩子B卖票,ticket = 10
票贩子B卖票,ticket = 8
票贩子A卖票,ticket = 9
票贩子A卖票,ticket = 6
票贩子C卖票,ticket = 9
票贩子C卖票,ticket = 4
票贩子A卖票,ticket = 5
票贩子B卖票,ticket = 7
票贩子B卖票,ticket = 1
***** 票已经卖光了 *****
票贩子A卖票,ticket = 2
***** 票已经卖光了 *****
票贩子C卖票,ticket = 3
***** 票已经卖光了 *****

在这里插入图片描述

class MyThread implements Runnable {
	private int ticket = 10 ; // 总票数为10张
	@Override
	public void run() {
		while (true) {
			if (this.ticket > 0) {
				try {
					Thread.sleep(100);	// 模拟网络延迟
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName() + "卖票,ticket = " + this.ticket --);
			} else {
				System.out.println("***** 票已经卖光了 *****");
				break ;
			}
		}
	}
}
public class Test { 
	public static void main(String[] args) throws Exception {
		MyThread mt = new MyThread() ;
		new Thread(mt,"票贩子A").start();
		new Thread(mt,"票贩子B").start();
		new Thread(mt,"票贩子C").start();
	}
}
票贩子C卖票,ticket = 10
票贩子B卖票,ticket = 8
票贩子A卖票,ticket = 9
票贩子C卖票,ticket = 7
票贩子A卖票,ticket = 6
票贩子B卖票,ticket = 5
票贩子C卖票,ticket = 4
票贩子A卖票,ticket = 2
票贩子B卖票,ticket = 3
票贩子C卖票,ticket = 1
***** 票已经卖光了 *****
票贩子B卖票,ticket = 0
***** 票已经卖光了 *****
票贩子A卖票,ticket = -1
***** 票已经卖光了 *****

在这里插入图片描述

在这里插入图片描述

三个线程都过了检测那一关

当多个线程访问同一资源的时候,我们如何能够保证数据的完整性,这个时候就需要用同步来解决了

2:线程同步-利用同步代码块进行处理

在这里插入图片描述

在这里插入图片描述

如果要想在程序之中实现这把锁的功能,就可以使用synchronized关键字来实现,利用此关键字可以定义同步方法或同步代码块,在同步代码块的操作里面的代码只允许一个线程执行。

在这里插入图片描述

观察下面的代码来解决上述问题中存在的问题;

class MyThread implements Runnable {
	private int ticket = 10 ; // 总票数为10张
	@Override
	public void run() {
		while (true) {
			synchronized(this) {	// 每一次只允许一个线程进行访问
				if (this.ticket > 0) {
					try {
						Thread.sleep(100);	// 模拟网络延迟
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName() + "卖票,ticket = " + this.ticket --);
				} else {
					System.out.println("***** 票已经卖光了 *****");
					break ;
				}
			}
		}
	}
}
public class Test { 
	public static void main(String[] args) throws Exception {
		MyThread mt = new MyThread() ;
		new Thread(mt,"票贩子A").start();
		new Thread(mt,"票贩子B").start();
		new Thread(mt,"票贩子C").start();
	}
}
//执行结果
票贩子A卖票,ticket = 10
票贩子C卖票,ticket = 9
票贩子C卖票,ticket = 8
票贩子B卖票,ticket = 7
票贩子B卖票,ticket = 6
票贩子B卖票,ticket = 5
票贩子B卖票,ticket = 4
票贩子B卖票,ticket = 3
票贩子B卖票,ticket = 2
票贩子B卖票,ticket = 1
***** 票已经卖光了 *****
***** 票已经卖光了 *****
***** 票已经卖光了 *****

上述代码加入了同步:加入同步处理之后,程序的整体性能下降了。同步实际上会造成性能的下降。

3;同步问题:利用同步方法解决:只需要在定义的方法上使用synchronized关键字即可

class MyThread implements Runnable {
	private int ticket = 10 ; // 总票数为10张
	public synchronized boolean sale() {
		if (this.ticket > 0) {
			try {
				Thread.sleep(100);	// 模拟网络延迟
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "卖票,ticket = " + this.ticket --);
			return true ;
		} else {
			System.out.println("***** 票已经卖光了 *****");
			return false ;
		}
	}
	@Override
	public void run() {
		while (this.sale()) {
			;
		}
	}
}
public class ThreadDemo { 
	public static void main(String[] args) throws Exception {
		MyThread mt = new MyThread() ;
		new Thread(mt,"票贩子A").start();
		new Thread(mt,"票贩子B").start();
		new Thread(mt,"票贩子C").start();
	}
}
//运行结果
票贩子B卖票,ticket = 10
票贩子B卖票,ticket = 9
票贩子C卖票,ticket = 8
票贩子C卖票,ticket = 7
票贩子C卖票,ticket = 6
票贩子C卖票,ticket = 5
票贩子C卖票,ticket = 4
票贩子C卖票,ticket = 3
票贩子C卖票,ticket = 2
票贩子C卖票,ticket = 1
***** 票已经卖光了 *****
***** 票已经卖光了 *****
***** 票已经卖光了 *****

在这里插入图片描述

4:死锁

在这里插入图片描述

在这里插入图片描述

public class Test implements Runnable {
	private Jian jj = new Jian() ;
	private XiaoQiang xq = new XiaoQiang() ;
	@Override
	public void run() {
		jj.say(xq);
	}
	public Test() {
		new Thread(this).start();
		xq.say(jj);
	}
	public static void main(String[] args) {
		new Test() ;
	}
}
class Jian {
	public synchronized void say(XiaoQiang xq) {
		System.out.println("阿健说:此路是我开,要想从此过,留下10块钱。");
		xq.get();
	}
	public synchronized void get() {
		System.out.println("阿健说:得到了10块钱,可以买饭吃了,于是让出了路。");
	}
}
class XiaoQiang {
	public synchronized void say(Jian jj) {
		System.out.println("小强说:让我先跑,我再给你钱。");
		jj.get();
	}
	public synchronized void get() {
		System.out.println("小强说:逃过了一劫,可以继续送快餐了。");
	}
}

执行效果如下;
在这里插入图片描述

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35649064/article/details/83958167