简单的使用synchronized关键字和Lock接口的练习

synchronized

package lock的使用;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MySynchronized {
	
	static String now() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = new Date();
		String now = sdf.format(d);
		//返回时间
		return now;
	}
	//log方法
	static void log(String msg) {
		System.out.printf("%s:%s%s%n",now(),Thread.currentThread().getName(),msg);
	}
	public static void main(String[] args) {
		final Object someObject = new Object();
		
		Thread t1 = new Thread() {
			@Override
			public void run() {
				//进度说明
				log("线程已经运行");
				log("线程试图占有someObject");
				//同步对象
				synchronized (someObject) {//synchronized同步代码块内的代码为关键逻辑代码,需要被保护的,以免产生脏数据
					log("线程占有someObject");
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					log("释放someObject");
				}
			}
		};
		t1.setName("T1");//设置名字
		t1.start();
		
		Thread t2 = new Thread() {
			@Override
			public void run() {
				//进度说明
				log("线程已经运行");
				log("线程试图占有someObject");
				//同步对象
				synchronized (someObject) {
					log("线程占有someObject");
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					log("释放someObject");
				}
			}
		};
		t2.setName("T2");
		t2.start();
	}
}

Lock接口

package lock的使用;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestMyLock {
	//时间
	static String now() {
		SimpleDateFormat sdf = new SimpleDateFormat();
		Date d = new Date();
		String now = sdf.format(d);
		return now;
	}
	
	//简化的说明
	static void log(String msg) {
		System.out.printf("%s:%s%s%n",now(),Thread.currentThread().getName(),msg);
	}
	
	public static void main(String[] args) {
		Lock lock = new ReentrantLock();
		
		Thread t1 = new Thread() {
			@Override
			public void run() {
				log("线程已经运行");
				log("线程试图占有lock");
				lock.lock();
				log("线程成功占有lock");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					log("线程结束");
					//关掉lock
					lock.unlock();
				}
			}
		};
		t1.setName("T1");
		t1.start();
		
		try {
			//让t1飞两秒
			Thread.sleep(2000);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		Thread t2 = new Thread() {
			@Override
			public void run() {
				log("线程已经运行");
				log("线程试图占有lock");
				lock.lock();//lock.lock()与lock.unlock()之间的代码为关键逻辑代码,需要被保护的,以免产生脏数据
				log("线程成功占有lock");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					log("线程结束");
					//关掉lock
					lock.unlock();
				}
			}
		};
		t2.setName("T2");
		t2.start();
	}
}

tyyLock()用法

package lock的使用;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestMyTrylock {
	//时间
	static String now() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = new Date();
		String now = sdf.format(d);
		return now;
	}
	//规范化的输出
	static void log(String msg) {
		
		System.out.printf("%s:%s%s%n",now(),Thread.currentThread().getName(),msg);
	}
	public static void main(String[] args) {
		Lock lock = new ReentrantLock();
		
		
		Thread t1 = new Thread() {
			@Override
			public void run() {
				boolean loked = false;//记录是否线程占用成功lock对象
				log("线程已经运行");
				log("线程视图占有lock对象");
				try {
					//设置线程最大等待时间两秒
					loked = lock.tryLock(2,TimeUnit.SECONDS);
					if(loked) {
						log("线程占有lock对象,并进行5秒的运算");
						Thread.sleep(5000);
					}else {
						log("线程经过两秒的努力没有成功占有lock对象");
					}
					log("线程结束");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					if(loked) {
						lock.unlock();
					}
				}
			}
		};
		t1.setName("T1");
		t1.start();
		
		Thread t2 = new Thread() {
			@Override
			public void run() {
				boolean loked = false;//记录是否线程占用成功lock对象
				log("线程已经运行");
				log("线程视图占有lock对象");
				try {
					loked = lock.tryLock(2,TimeUnit.SECONDS);
					if(loked) {
						log("线程占有lock对象,并进行5秒的运算");
						Thread.sleep(5000);
					}else {
						log("线程经过两秒的努力没有成功占有lock对象");
					}
					log("线程结束");
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					if(loked) {
						lock.unlock();
					}
				}
			}
		};
		t2.setName("T2");
		t2.start();
	}
}

使用lock进行线程交互

package lock的使用;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestMyLock {
	//时间
	static String now() {
		SimpleDateFormat sdf = new SimpleDateFormat();
		Date d = new Date();
		String now = sdf.format(d);
		return now;
	}
	
	//简化的说明
	static void log(String msg) {
		System.out.printf("%s:%s%s%n",now(),Thread.currentThread().getName(),msg);
	}
	
	public static void main(String[] args) {
		Lock lock = new ReentrantLock();
		//后边释放锁,唤醒其他线程需要使用下边这个类
        Condition condition = lock.newCondition();
        
		Thread t1 = new Thread() {
			@Override
			public void run() {
				log("线程已经运行");
				log("线程试图占有lock");
				lock.lock();
				log("线程成功占有lock");
				try {
					Thread.sleep(5000);
					
					//让线程临时释放锁让其他线程得到lock对象并运行
                    //此处使用lock的释放方法与synchronized略有不同
                    log("线程临时释放锁");
                    condition.await();//释放操作与synchronized的wait()对应
                    log("线程重新获得lock对象进行五秒的操作");
                    Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					log("线程结束");
					//关掉lock
					lock.unlock();
				}
			}
		};
		t1.setName("T1");
		t1.start();
		
		try {
			//让t1先跑两秒
			Thread.sleep(2000);
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		Thread t2 = new Thread() {
			@Override
			public void run() {
				log("线程已经运行");
				log("线程试图占有lock");
				lock.lock();//lock.lock()与lock.unlock()之间的代码为关键逻辑代码,需要被保护的,以免产生脏数据
				log("线程成功占有lock并进行5秒的操作");
				try {
					Thread.sleep(5000);
					condition.signal();//唤醒操作与synchronized的notify()对应  还有个signalAll()与notifyAll();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}finally {
					log("线程结束");
					//关掉lock
					lock.unlock();
				}
			}
		};
		t2.setName("T2");
		t2.start();
	}
}

简单描述synchronized关键字和Lock接口的区别

前者是java关键字是内置语言实现,后者是接口,然后就是lock需要每次结束手动释放锁,否则会造成死锁,再者使用synchronized容易造成死锁,必须代码逻辑严密不出错才能避免死锁,而lock有个trylock()方式可以设置抢占资源的时间,过了时间自动不抢了,有效避免死锁,然后就是synchronied中线程交互,被占用调用wait(),notify(),notifyAll()均来自Obejct超级父类。而lock接口中使用await(),signal(),signalAll()来自于Condition接口;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值