在java中创建线程的方式有两种:1, 继承Thread class 2, 实现 Runnable interface
对象锁
java中每一个对象都有一个唯一的对象锁,一个该对象的同步的方法(synchronized方法)在执行时必须要先获得这个对象锁,也就是说这个同步方法与该对象其它的同步方法是互斥的,从这个对象的角度来看,同步的方法就是原子的。
类锁
每一个类也拥有一个唯一的类锁,主要用于静态方法的同步,即同步的静态方法之间是互斥的,而类锁与对象锁是不冲突的,即对于同一个类的方法,同步的静态方法和同步的非静态方法是可以同时运行的
synchronized关键字
synchronized可以修饰方法或代码块,表示这个方法或这个代码块是同步的,修饰非静态的方法时,需要申请对象锁,修饰静态方法时需要申请类锁
sleep方法
方法申明:static void sleep(long milliseconds)
作用: 使当前线程休眠一段时间,线程休眠期间,不释放它所申请的各种锁,即一个同步线程在sleep时,同一个对象的同步方法无法运行
join方法
申明: void join()
void join(long timeout)
作用:
t.join() 或者t.join(100)
等待指定线程(t)运行结束,当线程不活动时,join会立刻返回
或者等待一个特定时间
wait方法
申明: void wait()
作用: 线程等待某种条件的发生。这是Object类的方法,而且必须在被同步的方法或者代码块中被调用
void wait(long timeout)
线程等待一定长的时间,作用类似于sleep(timeout),但是wait方法会释放线程申请的对象锁或者类锁,在wait完后在重新申请锁。
e.g.
synchronized void funa()
{
while(TestObject.canRun == false)
{
try{
wait();
}catch (Exception e) {}
}
System.out.println("after wait");
}
nofity 和notifyAll方法
申明:
void notify();
void notifyAll();
两方法都是Object方法。
作用: 通知在该对象上等待的线程其等待的条件已经发生了。必须在同步的方法或者代码块中调用
e.g.
synchronized void goOn()
{
TestObject.canRun = true;
this.notify();
}
两者的区别在于 :
notify()和notifyAll()都是Object对象用于通知处在等待该对象的线程的方法。两者的最大区别在于: notifyAll使所有原来在该对象上等待被notify的线程统统退出wait的状态,变成等待该对象上的锁,一旦该对象被解锁,他们就会去竞争。notify则文明得多他只是选择一个wait状态线程进行通知,并使它获得该对象上的锁,但不惊动其他同样在等待被该对象notify的线程们,当第一个线程运行完毕以后释放对象上的锁此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,继续处在wait状态,直到这个对象发出一个notify或notifyAll,它们等待的是被notify或notifyAll,而不是锁。

