多线程(2)

    技术2022-07-11  86

    目录

    线程的同步1. 同步代码块解决Runnable方式实现多窗口卖票2. 同步代码块解决继承Thread类实现多窗口卖票3. 同步方法解决Runnable方式实现多窗口卖票4.同步方法解决继承Thread类实现多窗口卖票


    线程的同步

    1. 同步代码块解决Runnable方式实现多窗口卖票

    使用同步代码块解决实现Runnable方式的线程安全问题。

    1.问题:卖票过程中,出现了重票、错票 —> 出现了线程的安全问题 2.问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其他线程参与进来,也操作车票。 3.如何解决:当一个线程a在操作ticket的时候,其他线程不能参与进来。直到线程a操作完ticket时,其他线程才可以操作ticket。这种情况即使线程a出现了阻塞,也不能被改变。 4.在Java中,我们通过同步机制,来解决线程的安全问题。

    方式一:同步代码块 synchronized(同步监视器){ //需要被同步的代码 }

    说明: 1.操作共享数据的代码,即为需要被同步的代码。 不能包含代码多了,也不能包含代码少了。 2.共享数据:多个线程共同操作的数据。比如:ticket就是共享数据。 3.同步监视器,俗称:锁。任何一个类的对象,都可以充当锁。 要求:多个线程必须要共用同一个锁。

    补充:在实现Runnable接口创建多线程的方式中,我们可以考虑使用this充当同步监视器。 在继承Thread类创建多线程的方式中,慎用this充当同步监视器,考虑使用当前类充当同步监视器。

    5.同步的方式,解决了线程的安全问题 —> 好处 操作同步代码时,只能有一个线程参与,其他线程等待。相当于是一个单线程的过程,效率低 —>坏处

    代码实现:

    /* 例子:创建三个窗口卖票,总票数为100张 */ public class WindowTest1 { public static void main(String[] args) { Window1 w = new Window1(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); } } class Window1 implements Runnable{ private int ticket = 100; Object obj = new Object(); @Override public void run() { while (true){ //synchronized (obj) { synchronized (this){ if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket); ticket--; } else { break; } } } } }

    2. 同步代码块解决继承Thread类实现多窗口卖票

    使用同步代码块解决继承Thread类的方式的线程安全问题 说明:在继承Thread类创建多线程的方式中,慎用this充当同步监视器。考虑使用当前类充当同步监视器。

    代码实现:

    /* 例子:创建三个窗口卖票,总票数为100张 */ public class WindowTest2 { public static void main(String[] args) { Window2 w1 = new Window2(); Window2 w2 = new Window2(); Window2 w3 = new Window2(); w1.setName("窗口1"); w2.setName("窗口2"); w3.setName("窗口3"); w1.start(); w2.start(); w3.start(); } } class Window2 extends Thread{ private static int ticket = 100; private static Object obj = new Object(); @Override public void run() { while (true){ //synchronized (obj){ synchronized (Window2.class){ //错误的使用 //synchronized (this){ if (ticket > 0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":卖票的票号为:" +ticket); ticket --; }else { break; } } } } }

    3. 同步方法解决Runnable方式实现多窗口卖票

    使用同步方法解决实现Runnable方式的线程安全问题。

    方式二:同步方法 如果操作共享数据的代码完整的声明在一个方法中,我们不妨将此方法声明同步的。

    1.同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。 2.非静态的同步方法,同步监视器是: this 静态的同步方法,同步监视器是:当前类本身

    代码实现:

    public class WindowTest3 { public static void main(String[] args) { Window3 w = new Window3(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); } } class Window3 implements Runnable{ private int ticket = 100; @Override public void run() { while (true){ show(); } } private synchronized void show(){//同步监视器:this if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket); ticket--; } } }

    4.同步方法解决继承Thread类实现多窗口卖票

    使用同步方法解决继承Thread类的方式的线程安全问题

    代码实现:

    /* 例子:创建三个窗口卖票,总票数为100张 */ public class WindowTest4 { public static void main(String[] args) { Window4 w1 = new Window4(); Window4 w2 = new Window4(); Window4 w3 = new Window4(); w1.setName("窗口1"); w2.setName("窗口2"); w3.setName("窗口3"); w1.start(); w2.start(); w3.start(); } } class Window4 extends Thread{ private static int ticket = 100; @Override public void run() { while (true){ show(); } } private static synchronized void show(){ if (ticket > 0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":卖票的票号为:" +ticket); ticket --; } } }

    多线程知识的学习 多线程(1):https://blog.csdn.net/weixin_45606067/article/details/107067785 多线程(3):https://blog.csdn.net/weixin_45606067/article/details/107067785 多线程(4):https://blog.csdn.net/weixin_45606067/article/details/107067785


    如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发。 创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客
    Processed: 0.013, SQL: 9