java多线程并发执行的时候,如果需要多线程依次操作共享数据的时候,就需要对共享数据进行同步操作,就需要对同步代码块或者是同步方法就行加锁,具体就是将共享数据奖赏synchronized关键字,这样一次只能有一个线程能够访问同步块中的数据,只有当该线程释放锁之后,别的对象获得了锁之后,才能 访问同步代码块或者是方法。
网上看到循环打印abc的一个例子 一并附上
wait()
使用方法
锁(即对象).wait() 。
作用:
该
方法用来将当前线程置入休眠状态,直到接到通知或被中断为止。条件:在调用wait()之前,线程必须要获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法。进入wait()方法后,当前线程释放锁。在从wait()返回前,线程与其他线程竞争重新获得锁。如果调用wait()时,没有持有适当的锁,则抛出IllegalMonitorStateException,它是RuntimeException的一个子类,因此,不需要try-catch结构。
notify()
使用方法 锁(对象).notify()
作用:唤醒其他休眠的线程中的一个,这个线程由系统确定。该方法也要在同步方法或同步块中调用,即在调用前,线程也必须要获得该对象的对象级别锁,的如果调用notify()时没有持有适当的锁,也会抛出IllegalMonitorStateException 一般情况下和wait()方法一起使用.
该方法用来通知那些可能等待该对象的对象锁的其他线程。如果有多个线程等待,则线程规划器任意挑选出其中一个wait()状态的线程来发出通知,并使它等待获取该对象的对象锁(notify后,当前线程不会马上释放该对象锁,wait所在的线程并不能马上获取该对象锁,要等到程序退出synchronized代码块后,当前线程才会释放锁,wait所在的线程也才可以获取该对象锁),但不惊动其他同样在等待被该对象notify的线程们。当第一个获得了该对象锁的wait线程运行完毕以后,它会释放掉该对象锁,此时如果该对象没有再次使用notify语句,则即便该对象已经空闲,其他wait状态等待的线程由于没有得到该对象的通知,会继续阻塞在wait状态,直到这个对象发出一个notify或notifyAll。这里需要注意:它们等待的是被notify或notifyAll,而不是锁。这与下面的notifyAll()方法执行后的情况不同。
notifyAll()
该方法与notify()方法的工作方式相同,重要的一点差异是:
notifyAll使所有原来在该对象上wait的线程统统退出wait的状态(即全部被唤醒,不再等待notify或notifyAll,但由于此时还没有获取到该对象锁,因此还不能继续往下执行),变成等待获取该对象上的锁,一旦该对象锁被释放(notifyAll线程退出调用了notifyAll的synchronized代码块的时候),他们就会去竞争。如果其中一个线程获得了该对象锁,它就会继续往下执行,在它退出synchronized代码块,释放锁后,其他的已经被唤醒的线程将会继续竞争获取该锁,一直进行下去,直到所有被唤醒的线程都执行完毕。
下面举一个例子
两个线程一次打印出AB两个字母 总共打印十次
class MultiThread
{
public static void main (String[] args) throws Exception
{
Object self=new Object();
Thread t1=new ThreadTest("a",self);
Thread t2=new ThreadTest("b",self);
t1.start();
t2.start();
}
}
class ThreadTest extends Thread
{
private Object self;
private String name;
private int count=0;
public ThreadTest(String name,Object self){
this.self=self;
this.name=name;
}
public void run() {
while(true){
synchronized(self){
System.out.println(name);
count++;
self.notify();
//self.notifyAll();//效果相同
if(count>=10){
break;
}
try {
self.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//System.out.println("释放锁");
}
}
}
网上看到循环打印abc的一个例子 一并附上
import java.util.concurrent.atomic.AtomicInteger;
public class TestAsynTreadXunlei {
public static void main(String argv[]) {
AtomicInteger synObj = new AtomicInteger(0);
TestPrint a = new TestPrint(synObj, "A", 0);
TestPrint b = new TestPrint(synObj, "B", 1);
TestPrint c = new TestPrint(synObj, "C", 2);
a.start();
b.start();
c.start();
}
}
class TestPrint extends Thread {
private AtomicInteger synObj;
private String name;
private int flag;
private int count = 0;
public TestPrint(AtomicInteger synObj, String name, int flag) {
this.synObj = synObj;
this.name = name;
this.flag = flag;
}
@Override
public void run() {
while (true) {
synchronized (synObj) {
if (synObj.get() % 3 == flag) {
synObj.set(synObj.get() + 1);
System.out.println(name);
count++;
synObj.notifyAll();
if (count == 10) {
break;
}
} else {
try {
synObj.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}