1. 程式人生 > >Java 內部類,多執行緒中Synchronized與wait,notify的使用

Java 內部類,多執行緒中Synchronized與wait,notify的使用

工作內容:

1.成員內部類    與成員方法,屬性的訪問許可權一致

2.靜態內部類    修飾符 stactic 類名{...}

3.匿名內部類    new 類名()/介面名(重寫介面方法)

4.區域性內部類    程式碼塊中

5.執行緒Thread wait,notify

學習分享:

誰去呼叫notify(),就解開誰,如果有多執行緒正在等待這個Object,則隨機執行一個執行緒

1)呼叫某個物件的wait()方法能讓當前執行緒阻塞,並且當前執行緒必須擁有此物件的monitor(即鎖)

2)呼叫某個物件的notify()方法能夠喚醒一個正在等待這個物件的monitor的執行緒,如果有多個執行緒都在等待這個物件的

monitor,則只能喚醒其中一個執行緒;

3)呼叫notifyAll()方法能夠喚醒所有正在等待這個物件的monitor的執行緒;

4) wait()和notifyAll()都應該放於synchorized同步程式碼塊中

注意:notify()notifyAll()方法只是喚醒等待該物件的monitor的執行緒,並不決定哪個執行緒能夠獲取到monitor

內部類例項:

public class Demo {

public static void main(String[] args) {

OuterClass out  = new OuterClass();

//成員內部類

out.new People1().speak("傳遞String"

);

//out.new People1().show();

//靜態內部類

//OuterClass.PeopleStatic.show();

}

}

public class OuterClass {

public static void main(String[] args) {

//測試同一個類中

OuterClass outer = new OuterClass();

//私有內部類的使用

outer.getPeople().show();

new OuterClass(). new People().show();

//成員內部類的使用

OuterClass.People1 people1 = outer.new

 People1();

people1.speak("傳遞String");

//靜態內部類

int z = OuterClass.PeopleStatic.speak(3,5);

System.out.println(z);

}

//私有內部類

private class People{

public void show(){

System.out.println("成員內部類");

}

}

public People getPeople(){

return new People();

}

public void getInstance(){

new People().show();

}

//成員內部類

String string = "外部類string";

class People1{

String string = "內部類string";

public void speak(String string){

System.out.println(string);//傳遞的string

System.out.println(this.string);//內部類的string

System.out.println(OuterClass.this.string);//外部類string

}

private void show(){

System.out.println("成員內部類show");

}

}

//靜態內部類

private static class PeopleStatic{

/**

 * 靜態內部類的方法需在外面打點呼叫,則方法必須是靜態方法

 * 靜態內部類的方法需在外面生成物件,可以物件打點呼叫非private ,static修飾的方法

 * @param x

 * @param y

 * @return

 */

private static int  speak(int x,int y){

return x*y;

}

public static void show(){

System.out.println("靜態內部類 靜態方法show");

}

}

}

例項2:

//測試synchronized(obj){}中wait和notify的使用

public class StaticObjectTestLock {
public static Object a = new Object();
public static Object b = new Object();
public static Object c = new Object();
public static Object d = new Object();
static int x=6;
public static void main(String[] args) throws InterruptedException {
new LockObj(1).start();
//呼叫sleep保證其順序執行
Thread.sleep(500);
new LockObj(3).start();
Thread.sleep(500);
new LockObj(2).start();
Thread.sleep(500);
new LockObj(4).start();
}
}
class LockObj extends Thread{
public int x;
public LockObj(int x) {
this.x = x ;
}
@Override
public void run() {
if(this.x == 1){
while (x<10) {
x++;
synchronized(StaticObjectTestLock.a){
System.out.println("A執行A wait");
try {
StaticObjectTestLock.a.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
if(this.x == 2){
while (x<10) {
x++;
synchronized(StaticObjectTestLock.b){
System.out.println("B執行,解開C");
synchronized(StaticObjectTestLock.c){
StaticObjectTestLock.c.notify();
//System.out.println("1111");
}
try {
StaticObjectTestLock.b.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
if(this.x ==3){
while (x<10) {
x++;
synchronized(StaticObjectTestLock.c){
System.out.println("C執行C wait");
synchronized (StaticObjectTestLock.a) {
//System.out.println("申請成功,C wait");
}
try {
StaticObjectTestLock.c.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
if(this.x ==4){
while (x<10) {
x++;
synchronized(StaticObjectTestLock.d){
System.out.println("D執行,解開C");
synchronized (StaticObjectTestLock.c) {
//System.out.println("解開C, D wait");
StaticObjectTestLock.c.notify();
}
try {
StaticObjectTestLock.d.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}