实现Runnable的线程同步块
package synchronization.block; /* @author zsben @create 2020-01-03 13:48 创建三个窗口卖票,使用Runnable接口方式 1.问题:卖票过程中出现了重票,错票-->出现了线程安全问题 2.解决方案:当一个线程在操作ticket时,其他线程不能参与进来(即使该线程被阻塞) 直到该线程操作完ticket,其他线程才可以参与进来, 3.java中通过同步机制进行解决 方式一:同步代码块 synchronized(同步监视器){ //需要被同步的代码 } 说明:1.操作共享数据的代码,即需要被同步的代码 2.共享数据:多个线程共同操作的变量(ticket) 3.同步监视器:锁,任何对象都可以充当锁 要求:多个线程必须要共用一把锁,可以考虑使用this来充当同步监视器 */ class WindowRun implements Runnable{ private int ticket = 100; Object obj = new Object(); @Override public void run() { synchronized(this){ //此时this代表唯一的WindowRun对象,可以替代new obj while (true) { if (ticket > 0) { System.out.println(Thread.currentThread().getName() + ": " + ticket); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } ticket--; } else break; } } } } public class WindowRunnableTest { public static void main(String[] args) { WindowRun windowRun = new WindowRun(); Thread t1 = new Thread(windowRun); Thread t2 = new Thread(windowRun); Thread t3 = new Thread(windowRun); t1.start(); t2.start(); t3.start(); } }
继承Thread的同步块
package synchronization.block; /* 创建三个窗口买票,总票数为100张 存在线程安全问题:使用同步代码块解决继承Thread类的方式线程安全问题 可以考虑使用当前类来充当同步监视器 @author zsben @create 2020-01-03 12:41 */ class Window extends Thread{ private static int ticket = 100; private static Object obj = new Object(); @Override public void run() { while (true) { synchronized (Window.class) { //拿当前类对象充当锁,Class clazz = Window2.class,Window2.class只会加载一次 if (ticket > 0) { try { sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getName() + ": " + ticket); ticket--; } else { break; } } } } } public class WindowThreadTest { public static void main(String[] args) { Window t1 = new Window(); Window t2 = new Window(); Window t3 = new Window(); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); } }
原文地址:https://www.cnblogs.com/zsben991126/p/12148291.html
时间: 2024-10-11 10:40:45