Runnable
package com.westos.Runnable; public class MyRunnable implements Runnable{ /** * 同步锁的对象可以是任意的java类对象 * 例如我们在下方定义一个Dome类,并在此创建Dome类对象 * 然后将同步锁的对象换成Dome类对象,依旧可以模拟现实窗口售票 */ private Dome d=new Dome(); //定义一个私有公用的票数变量 private static int tickets=100; 定义同一把锁对象 //private Object obj=new Object(); @Override public void run() { while(true) { /** * 为了多个线程可以享用到共享资源我们必须的设置同一把锁,不然依旧会出现好几个窗口在出售同一张票的情况 * 这里的synchronized()方法就好比是一扇门,当其中的一个线程进来后就会关闭这扇门,然后去享受资源 * 等它享受完后,下一个线程会继承抢着进来享受资源,每一线程进来后 * 共享代码块就会发挥它的作用,这样就不会出现同票和负票的现象了 */ synchronized (d) { if(tickets>0) { //模范现实售票延迟的效果,给线程加入睡眠的功能(睡眠100毫秒) try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } //因为上面是运用了实现Runnable接口的方法,不能直接调用getName方法,当你使用继承Thread类方式时,就可以使用了 //必须通过Thread类中的返回正在运行的线程的方法再用它去调用getName方法 System.out.println(Thread.currentThread().getName()+"正在出售第"+(tickets--)+"张票"); } } } } class Dome{ } }package com.westos.Runnable; /** * 当我们模拟现实售票的情况时,会出现窗口出售同一张票的情况以及出现负票的情况 * (例如窗口1正在出售第0张票或者窗口1正在出售第-1张票的情况) *解决方法: * 将我们的共享数据用同步代码块包起来 * 格式synchronized(锁对象){ * 多条语句对共享数据的使用代码 * } * */ public class RunnableDome { public static void main(String[] args) { //创建资源类对象 MyRunnable my=new MyRunnable(); //创建Thread类对象 Thread t1=new Thread(my,"窗口1"); Thread t2=new Thread(my,"窗口2"); Thread t3=new Thread(my,"窗口3"); //执行线程 t1.start(); t2.start(); t3.start(); } }.class
package com.westos.Runnable; public class SellTicket implements Runnable{ //创建Dome类对象 Dome d=new Dome(); //定义一个通用的票数 private static int ticket=100; //定义一个变量 private int x=0; @Override public void run() { //循环 while(true) { if(x%2==0) { synchronized (SellTicket.class) {//当方法时静态时:锁对象:类名.class; 当方法不是静态时,锁对象是this if(ticket>0) { //让共享资源睡眠0.1秒 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在出售第"+(ticket--)+"张票"); } } } else { sellTicket(); } x++; } } //我们可以将同步锁写在方法中,然后在run方法中调用即可 /*private void sellTicket() { synchronized (d) { if(ticket>0) { //让共享资源睡眠0.1秒 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在出售第"+(ticket--)+"张票"); } } }*/ //或者我们可以直接把同步锁写在方法上去调用 //当该方法时静态的时候,该类中的锁对象是类名.class private synchronized static void sellTicket() { if(ticket>0) { //让共享资源睡眠0.1秒 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在出售第"+(ticket--)+"张票"); } } class Dome{ } }package com.westos.Runnable; public class SellTicketDome { public static void main(String[] args) { //创建资源类对象 SellTicket st=new SellTicket(); //创建三个Thread类对象 Thread t1=new Thread(st,"窗口1"); Thread t2=new Thread(st,"窗口2"); Thread t3=new Thread(st,"窗口3"); //启动线程 t1.start(); t2.start(); t3.start(); } } 运行结果: 窗口2正在出售第7张票 窗口3正在出售第6张票 窗口1正在出售第5张票 窗口1正在出售第4张票 窗口3正在出售第3张票 窗口3正在出售第2张票 窗口3正在出售第1张票StringBufferVectorHashtable
package com.westos.synchronizedList; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; import java.util.List; import java.util.Vector; public class synchronizedListDome { public static void main(String[] args) { //目前我们学习过的线程安全的类有: StringBuffer sb=new StringBuffer(); Vector v=new Vector(); Hashtable ht=new Hashtable(); /** * 但是当我们运用一些集合的时候还是习惯用ArrayList集合 * 所以我们应该怎么将一些线程不安全的类转变成线程安全 的类呢 * 接下来就需要运用到collections工具类的synchronizedList方法了 */ //创建ArrayList集合对象,将类型定为String类型 ArrayList<String> list=new ArrayList<String>(); //调用方法://public static <T> List<T> synchronizedList(List<T> list) //返回是List集合,返回的集合就是线程安全的类了 List<String> array = Collections.synchronizedList(list); } }
文章来源: 同步锁的理解以及转变安全集合的方法