线程的同步与死锁.

xiaoxiao2021-02-28  25

同步

     同步是多线程开发中的一个重要概念,但是既然有同步,那么就一定会存在有不同步的操作。所以本节将为读者分析线程不同步所带来的影响。

     多个线程操作同一资源时就有可能出现不同步的问题,例如,现在产生N个线程对象实现卖票操作,同时为了更加明显的观察到不同步所带来的问题,所以本程序将使用线程的休眠操作。

class MyThread implements Runnable { private int ticket = 5; // 一共有5张票 @Override public void run() { for (int x = 0; x < 20; x++) { if (this.ticket > 0) { // 判断当前是否还有剩余票 try { Thread.sleep(100); // 休眠1秒,模拟延迟 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 卖票,ticket = " + this.ticket--); } } } } public class TestDemo { 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(); // 启动多线程 new Thread(mt, "票贩子D").start(); // 启动多线程 } }

Synchronized

     在Java里面如果要想实现线程的同步可以使用synchronized关键字。而这个关键字可以通过两种方式使用:

     同步代码块,利用synchronized包装的代码块,但是需要指定同步对象,一般设置为this;

     同步方法,利用synchronized定义的方法。

观察同步块

class MyThread implements Runnable { private int ticket = 5; // 一共有5张票 @Override public void run() { for (int x = 0; x < 20; x++) { synchronized(this) { // 定义同步代码块 if (this.ticket > 0) { // 判断当前是否还有剩余票 try { Thread.sleep(100); // 休眠1秒,模拟延迟 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 卖票,ticket = " + this.ticket--); } } } } } public class TestDemo { 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(); // 启动多线程 new Thread(mt, "票贩子D").start(); // 启动多线程 } }

使用同步方法解决问题

class MyThread implements Runnable { private int ticket = 5; // 一共有5张票 @Override public void run() { for (int x = 0; x < 20; x++) { this.sale(); // 卖票操作 } } public synchronized void sale() { // 同步方法 if (this.ticket > 0) { // 判断当前是否还有剩余票 try { Thread.sleep(100); // 休眠1秒,模拟延迟 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " 卖票,ticket = " + this.ticket--); } } }

死锁

     同步就是指一个线程要等待另外一个线程执行完毕才会继续执行的一种操作形式,虽然在一个程序中,使用同步可以保证资源共享操作的正确性,但是过多同步也会产生问题。例如:现在有张三想要李四的画,李死想要张三的书,那么张三对李四说了:“把你的画给我,我就给你书”,李四也对张三说了:“把你的书给我,我就给你画”,此时,张三在等着李四的答复,而李四也在等着张三的答复,那么这样下去最终结果可想而知,张三得不到李四的画,李四也得不到张三的书,这实际上就是死锁的概念

   

程序死锁操作

class A { public synchronized void say(B b) { System.out.println("A先生说:把你的本给我,我给你笔,否则不给!"); b.get(); } public synchronized void get() { System.out.println("A先生:得到了本,付出了笔,还是什么都干不了!"); } } class B { public synchronized void say(A a) { System.out.println("B先生说:把你的笔给我,我给你本,否则不给!"); a.get(); } public synchronized void get() { System.out.println("B先生:得到了笔,付出了本,还是什么都干不了!"); } } public class TestDemo implements Runnable { private static A a = new A(); // 定义类对象 private static B b = new B(); // 定义类对象 public static void main(String[] args) throws Exception { new TestDemo(); // 实例化本类对象 } public TestDemo() { // 构造方法 new Thread(this).start(); // 启动线程 b.say(a); // 互相引用 } @Override public void run() { a.say(b); // 互相引用 } }
转载请注明原文地址: https://www.6miu.com/read-2350174.html

最新回复(0)