同步锁的理解以及转变安全集合的方法

匿名 (未验证) 提交于 2019-12-03 00:22:01

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); } }

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!