java 线程安全问题
1.同步代码块
1.1 使用 synchronized 解决 Runnable 线程安全问题
ps: 使用同一个obj 的锁
package com.cj; class WindowsTest2 implements Runnable{ private int ticket = 100; Object obj = new Object(); public void run() { while (true){ synchronized (obj){ if(ticket>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖票:"+"票号:"+ticket); ticket--; }else{ break; } } } } } class Test2{ public static void main(String[] args) { WindowsTest2 windowsTest2 = new WindowsTest2(); Thread w1 = new Thread(windowsTest2); Thread w2 = new Thread(windowsTest2); Thread w3 = new Thread(windowsTest2); w1.setName("窗口1"); w2.setName("窗口2"); w3.setName("窗口3"); w1.start(); w2.start(); w3.start(); } }
1.2 解决 extends Thread 线程安全问题
package com.cj; class WindowsTest extends Thread{ private static int ticket = 100; private static Object obj = new Object(); @Override public void run() { while (true){ synchronized (obj){ if(ticket>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖票:"+"票号:"+ticket); ticket--; }else{ break; } } } } } class Test{ public static void main(String[] args) { WindowsTest w1 = new WindowsTest(); WindowsTest w2 = new WindowsTest(); WindowsTest w3 = new WindowsTest(); w1.setName("窗口1"); w2.setName("窗口2"); w3.setName("窗口3"); w1.start(); w2.start(); w3.start(); } }
2 同步方法
package com.cj; public class WindowsTest3 implements Runnable{ private int ticket = 100; public void run() { while (true){ show(); } } public synchronized void show(){ if(ticket>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "卖票:"+"票号:"+ticket); ticket--; } } } class Test3{ public static void main(String[] args) { WindowsTest3 windowsTest3 = new WindowsTest3(); Thread w1 = new Thread(windowsTest3); Thread w2 = new Thread(windowsTest3); Thread w3 = new Thread(windowsTest3); w1.setName("窗口1"); w2.setName("窗口2"); w3.setName("窗口3"); w1.start(); w2.start(); w3.start(); } }