java基础-多线程01之lock/unlock,semphore,volatile

举一个例子来解释java多线程同步锁的用法:有first,second,third,forth四个线程,first输出1,second输出2,third输出3,forth输出4。要求, 同时启动四个线程, 按顺序输出1234, 且未无限循环输出。

首先是jdk5的lock和unclock,lock表示Lock对象执行了锁定操作,其他的线程都必须等这个线程完成,unlock则并释放锁之后,才能执行被锁住的代码块。

public class Test1  {
 private static int state = 0;
 private static Lock lock  = new ReentrantLock();//通过JDK5中的锁来保证线程的访问的互斥
 public static void main(String[] args) {
  First first = new First();
  Second second = new Second();
  Third third = new Third();
  Forth forth = new Forth();
  first.start();
  second.start();
  third.start();
  forth.start();
  
 }
 
 static class First extends Thread{
  
  @Override
  public void run() {
   while(true){
    lock.lock();
    if(state % 4 ==0){
     state++;
     System.out.println(0);
    }
    lock.unlock();
   }
  }
 }
 
 static class Second extends Thread{
  
  @Override
  public void run() {
   while(true){
    lock.lock();
    if(state % 4 ==1){
     state++;
     System.out.println(1);
    }
    lock.unlock();
   }
  }
   }
   
 static  class Third extends Thread{
  
   @Override
   public void run() {
    while(true){
     lock.lock();
     if(state % 4 ==2){
      state++;
      System.out.println(3);
     }
     lock.unlock();
    }
   }
    }
 
 static class Forth extends Thread{
  
  @Override
  public void run() {
   while(true){
    lock.lock();
    if(state % 4 ==3){
     state++;
     System.out.println(4);
    }
    lock.unlock();
   }
  }
   }
   
 
}


最终输出的结果是无序的,因为4个线程同时争夺cpu的执行权。

接下来是:Semphore(翻译过来就是信号的意思)

Semphore,完成对信号量的控制,可以控制某个资源可以被同时访问的个数,通过acquire()获取一个许可,如果没有就等待,而release()释放一个许可。通过代码可以更好的理解


public class Test2 {   public static Semaphore sem1;      public static Semaphore sem2;   public static Semaphore sem3;   public static Semaphore sem4;      static class First extends Thread{  @Override  public void run() {    try {           while(true){       sem1.acquire();  //sem1的资源数减一后,资源数为0,然后自己阻塞起来       System.out.println(1);       sem2.release();  //sem2资源数加一,不再为0,可以开始运行         }     }catch (InterruptedException e) {     // TODO 自动生成的 catch 块    e.printStackTrace();   }  }   }   static class Second extends Thread{   @Override   public void run() {     try {            while(true){        sem2.acquire();              System.out.println(2);        sem3.release();          }      }catch (InterruptedException e) {      // TODO 自动生成的 catch 块     e.printStackTrace();    }   }    }    static class Third extends Thread{  @Override  public void run() {    try {           while(true){       sem3.acquire();            System.out.println(3);       sem4.release();         }     }catch (InterruptedException e) {     // TODO 自动生成的 catch 块    e.printStackTrace();   }  }   }   static class Forth extends Thread{  @Override  public void run() {    try {           while(true){       sem4.acquire();            System.out.println(4);       sem1.release();         }     }catch (InterruptedException e) {     // TODO 自动生成的 catch 块    e.printStackTrace();   }  }   }   public static void main(String[] args) {     sem1 = new Semaphore(1);        sem2 = new Semaphore(1);        sem3 = new Semaphore(1);        sem4 = new Semaphore(1); //1代表是1个信号量,也可以理解为资源数,进行初始化用的        try {            // 不要有sem1.acquire()            sem2.acquire();  //把sem2初始化时候给的资源数全部减1,只让sem1拥有资源数            sem3.acquire();            sem4.acquire();        } catch (InterruptedException e) {            e.printStackTrace();        }
  First first = new First();  Second second = new Second();  Third third = new Third();  Forth forth = new Forth();    first.start();  second.start();  third.start();  forth.start();  }

最终结果为:

补充知识点:volatile,保证被修饰的变量在读写前都会与主存交互更新。一个变量被volatile修饰后,则不同线程对这个变量进行操作时,总是从内存中读取最新值,即每次更新对其他线程都是立即可见的。注意立即可见这几个字。。

public class Test3 {
	  volatile static int state = 0; 
	  static class First extends Thread{
		@Override
		public void run() {
			while(true){
				if(state%4==0){
					System.out.println("1");
                    state++;
				}
			}
		}
	  }
	  static class Second extends Thread{
			@Override
			public void run() {
				while(true){
					if(state%4==1){
						System.out.println("2");
	                    state++;
					}
				}
			}
		  }
	  	static class Third extends Thread{
		@Override
		public void run() {
			while(true){
				if(state%4==2){
					System.out.println("3");
                    state++;
				}
			}
		}
	  }
	  static class Forth extends Thread{
		@Override
		public void run() {
			while(true){
				if(state%4==3){
					System.out.println("4");
                    state++;
				}
			}
		}
	  }
	  public static void main(String[] args) {

		First first = new First();
		Second second = new Second();
		Third third = new Third();
		Forth forth = new Forth();
		
		first.start();
		second.start();
		third.start();
		forth.start();
	 }
	  
}
最终结果为:


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值