package com.java.test;
public class Test5 {
/**
* Java多线程实现有两种实现方法,分别是继承Thread类,重写run()方法与实现Runnable接口
* sleep与wait区别:
* sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁
* wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程
*才进入对象锁定池准备获得对象锁进入运行状态(notify并不释放锁,只是告诉调用过wait方法的线程可以去参与获得锁的竞争了,但不是马上得到锁,因为锁还在别
* 人手里,别人还没释放。如果notify方法后面的代码还有很多,需要这些代码执行完后才会释放锁)
*/
public static void main(String[] args) {
T1 t1 = new T1();
t1.start();
new Thread(new T2()).start();
}
}
class T1 extends Thread{
public void run(){
synchronized(Test5.class){
System.out.println("enter T1...");
System.out.println("T1 is waiting");
try {
//释放锁有两种方式,第一种方式是程序自然离开监视器的范围,也就是离开了synchronized关键字管辖的代码范围,
//另一种方式就是在synchronized关键字管辖的代码内部调用监视器对象的wait方法。这里,使用wait方法释放锁
Test5.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T1 is going on");
System.out.println("T1 is being over");
}
}
}
class T2 implements Runnable{
@Override
public void run() {
synchronized(Test5.class){
System.out.println("enter T2..");
System.out.println("T2 notify other thread can release wait status..");
Test5.class.notify();
//由于notify方法并不释放锁,即使T2调用下面的sleep方法休息了10毫秒,但T1仍然不会执行,因为T2没有释放锁,所以T1无法得不到锁。
System.out.println("T2 will sleep ten millisecond..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T2 is going on");
System.out.println("T2 is being over");
}
}
}
运行结果:
enter T1...
T1 is waiting
enter T2..
T2 notify other thread can release wait status..
T2 will sleep ten millisecond..
T2 is going on
T2 is being over
T1 is going on
T1 is being over
package com.java.test;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test6 {
/**
*
* @Lock和synchronized区别
* 主要相同点:Lock能完成synchronized所实现的所有功能 主要不同点:Lock有比synchronized更精确的线程语义和更好的性能。
* synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。Lock还有更强大的功能,例如,它的tryLock方法可以非阻塞方式去拿锁。
* synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,
* 要保证锁定一定会被释放,就必须将unLock()放到finally{}中
* 在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态;
*
*
*ReentrantLock获取锁定与三种方式:
*<1>lock(), 如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
*<2>tryLock(), 如果获取了锁立即返回true,如果别的线程正持有锁,立即返回false;
*<3>tryLock(long timeout,TimeUnit unit), 如果获取了锁定立即返回true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回true,如果等待超时,返回false;
*<4>lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断
*
*
*
*/
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Consumer c = new Consumer(lock);
Producer p = new Producer(lock);
new Thread(c).start();
new Thread(p).start();
}
}
class Consumer implements Runnable{
private Lock lock;
public Consumer(Lock lock){
this.lock = lock;
}
@Override
public void run() {
int count = 3;
while(count>0){
try{
lock.lock();
count--;
System.out.println("consumer A");
}finally{
lock.unlock();
}
}
}
}
class Producer implements Runnable{
private Lock lock;
public Producer(Lock lock){
this.lock = lock;
}
@Override
public void run() {
int count = 3;
while(count>0){
try{
lock.lock();
count--;
System.out.println("producer B");
}finally{
lock.unlock(); }
}
}
}