日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java学习笔记十五

發布時間:2024/2/28 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java学习笔记十五 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


26.

下面介紹synchronized代碼塊,個人以為,重要度遠遠高于單純的修飾synchronized方法:

一方面:高效率!

另一方面:后面涉及到的wait和notify方法,都要涉及

Synchronized要修飾一個對象

即:synchronized(Object);

表示將對象object上鎖,這里的object對象其實是沒有用的,只是說明被上鎖,個人建議使用this關鍵字,表示將當前對象上鎖!

看下面的synchronized代碼塊代碼同樣實現了兩個方法的順序執行:

?

?

?

package thread;

?

public class BlockTest

{

?? public static void main(String[] args)

?? {

????? Block block = new Block();

????? ThreadTestX test1 = new ThreadTestX(block);

????? ThreadTestXX test2 = new ThreadTestXX(block);

????? test1.start();

????? test2.start();

?? }

}

class Block

{

?? public void method1()

?? {

????? synchronized (this)

????? {

??????? for(int i = 0; i < 15; i++)

??????? {

?????????? System.out.println("hello :"+ i);

??????????

??????? ??

??????? }

????? }

?? }

?? public void method2()

?? {

????? synchronized(this)

????? {

??????? for(int i = 0 ; i <15; i ++)

??????? {

?????????? System.out.println("world!"+ i);

??????????

??????? }

????? }

?? }

}

class ThreadTestXextends Thread

{

?? private Blockblock;

?? public ThreadTestX(Block block)

?? {

????? this.block = block;

?? }

?? @Override

?? public void run()

?? {

????? block.method1();

?? }

??

}

class ThreadTestXXextends Thread

{

?? private Blockblock;

?? public ThreadTestXX(Block block)

?? {

????? this.block = block;

?? }

?? @Override

?? public void run()

?? {

????? block.method2();

?? }

??

}

?

?

?

27.

Deadlock:

所謂死鎖<DeadLock>:是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去.此時稱系統處于死鎖狀態或系統產生了死鎖,這些永遠在互相等待的進程稱為死鎖進程.

產生deadlock的四個必要條件:

  (1) 互斥條件:一個資源每次只能被一個進程使用。

  (2) 請求與保持條件:一個進程因請求資源而阻塞時,對已獲得的資源保持不放。

  (3) 不剝奪條件:進程已獲得的資源,在末使用完之前,不能強行剝奪。

  (4) 循環等待條件:若干進程之間形成一種頭尾相接的循環等待資源關系。

  這四個條件是死鎖的必要條件,只要系統發生死鎖,這些條件必然成立,而只要上述條件之

  一不滿足,就不會發生死鎖。

?

28.

一個線程就是一個類!

?

?

29.

Object類中的wait 、和 notify方法是用來處理線程的方法,既然定義在Object類中,兩個方法的重要程度可見一斑:

兩個方法的使用上都很復雜:通過閱讀API獲得更多對方法的理解:

The current thread must own this object'smonitor. The thread releases ownership of this monitor and waits until anotherthread notifies threads waiting on this object's monitor to wake up eitherthrough a call to thenotify method or the notifyAll method. The thread then waits until it can re-obtain ownership ofthe monitor and resumes execution

?

?

“當前的線程必須要獲得對象的鎖!”

實現這個條件的做法就是wait 方法一定要定義在synchronized方法中或者synchronized代碼塊中;

線程必須要兩次獲得鎖才能完全的執行synchronized中的所有內容;

當第一次調用到達wait方法時,The thread realeases ownership of this monitor and waituntil another thread notifies threads waiting on this …

線程會暫時釋放鎖的擁有權,等待其他線程的notify方法或者notifyAll方法喚醒該線程,繼續執行代碼!

?

?

?

30.

下面一個程序要求定義兩個線程類,一個實現將目標加一,一個實現將目標減一,目標初始值為零,要求加一減一交替進行;

顯然的單純調用synchronized是無法滿足條件的,需要使用wait,和notify方法;

?

package thread;

?

public class ThreadTest

{

?

?? public static void main(String[] args)

?? {

????? ThreadDemo2 demo = new ThreadDemo2();

????? ThreadIncrease test1 = new ThreadIncrease(demo);

????? ThreadDecrease test2 = new ThreadDecrease(demo);

????? test1.start();

????? test2.start();

?? }

}

class ThreadDemo2

{

?? private int num = 0;

?? public synchronized void Increase()

?? {

????? /*

????? ?* 下面的代碼是核心代碼

????? ?* 什么時候要讓線程等待,當然是不符合條件的時候

????? ?* 目的是想讓num = 0的時候才執行加一的操作,當num不等于零的時候會執行wait等待通知

????? ?* 當通知num已經變為0時,wait結束,執行下面語句num++;

????? ?* 然后執行notify方法!

????? ?* 當然的一說Java中的synchronized總是伴隨著waitnotify方法共同的存在;

????? ?*/

?????

????? if(num != 0)

????? {

??????? try

??????? {

?????????? wait();

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

????? }

????? num ++;

????? System.out.println(num);

????? notify();

????? }

??

?? public synchronized void decrease()

?? {

?????

????? if(num == 0)

????? {

??????? try

??????? {

?????????? wait();

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

????? }

????? num --;

????? System.out.println(num);

?????

????? notify();

????? }

?????

??

}

class ThreadIncreaseextends Thread

{

?? private ThreadDemo2demo;

?? public ThreadIncrease(ThreadDemo2 demo)

?? {

????? this.demo = demo;

?? }

?? @Override

?? public void run()

?? {

????? for(int i = 0 ; i < 15; i ++)

????? {

????? demo.Increase();

????? }

?? }

??

}

class ThreadDecreaseextends Thread

{

?? private ThreadDemo2demo;

?? public ThreadDecrease(ThreadDemo2 demo)

?? {

????? this.demo = demo;

?????

?? }

?? @Override

?? public void run()

?? {

????? for(int i = 0 ; i < 15; i ++)

????? {

????? demo.decrease();

????? }

?? }

}

?

?

?

31.

可惜的是上面的代碼仍然有著致命的弱點,線程并不僅僅有兩個,而且是兩個相對的線程!

致命的弱點在于: 當線程在wait的時候它并不知道其他的線程到底做了什么!

現在我們將增加一個Increase線程類,和一個Decrease線程類

,并且調用它們的start方法運行后,你將看到這樣的結果:

我們足以看到代碼的脆弱性,為什么會出現這種情況,更糟糕的是結果是隨機的!上面已經說得很清楚了:當線程在wait的時候,它不知道其他的線程正在做什么,

所以需要將代碼變得更加健壯:

我們舉一個為什么會出現這種情況的原因之一:

我們假設線程1、2調用增加方法,線程3、4調用減少方法

假設線程3 先訪問了減少方法,因為此時num的值為0,所以wait,并且交出ownership,假設線程4又訪問了減少方法,同樣的wait,并且交出所有權,再假設線程1訪問了增加方法,將num的值變為1,并且調用notify方法,假設notify了線程3,線程3將num的值變為0;并且notify,如果此時notify了線程4,那么悲劇就會發生了,線程4醒來后,會繼續將num減一,變為-1,一步錯,后面就全錯了;

缺點就在于notify的隨機性,所以在某個wait方法被喚醒時,增加判斷條件,如果不符合條件,繼續wait,顯然 while循環是最合適的

!

全部的變化只需要將 if 改為 while!!

由于num是成員變量被線程共享,每當wait被喚醒,都會判斷一次;

package thread;

?

public class ThreadTest

{

?

?? public static void main(String[] args)

?? {

????? ThreadDemo2 demo = new ThreadDemo2();

????? ThreadIncrease test1 = new ThreadIncrease(demo);

????? ThreadDecrease test2 = new ThreadDecrease(demo);

????? ThreadIncrease test3 = new ThreadIncrease(demo);

????? ThreadDecrease test4 = new ThreadDecrease(demo);

????? test1.start();

????? test2.start();

????? test3.start();

????? test4.start();

?? }

}

class ThreadDemo2

{

?? private int num = 0;

?? public synchronized void Increase()

?? {

????? /*

????? ?* 下面的代碼是核心代碼

????? ?* 什么時候要讓線程等待,當然是不符合條件的時候

????? ?* 目的是想讓num = 0的時候才執行加一的操作,當num不等于零的時候會執行wait等待通知

????? ?* 當通知num已經變為0時,wait結束,執行下面語句num++;

????? ?* 然后執行notify方法!

????? ?* 當然的一說Java中的synchronized總是伴隨著waitnotify方法共同的存在;

????? ?*/

?????

?? ?? while(num != 0)

????? {

??????? try

??????? {

?????????? wait();

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

????? }

????? num ++;

????? System.out.println(num);

????? notify();

????? }

??

?? public synchronized void decrease()

?? {

?????

????? while(num == 0)

????? {

??????? try

??????? {

?????????? wait();

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

????? }

????? num --;

????? System.out.println(num);

?????

????? notify();

????? }

?????

??

}

class ThreadIncreaseextends Thread

{

?? private ThreadDemo2demo;

?? public ThreadIncrease(ThreadDemo2 demo)

?? {

????? this.demo = demo;

?? }

?? @Override

?? public void run()

?? {

????? for(int i = 0 ; i < 15; i ++)

????? {

??????? try

??????? {

?????????? Thread.sleep((long)(Math.random()*1000));

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

??????? demo.Increase();

????? }

?? }

??

}

class ThreadDecreaseextends Thread

{

?? private ThreadDemo2demo;

?? public ThreadDecrease(ThreadDemo2 demo)

?? {

????? this.demo = demo;

?????

?? }

?? @Override

?? public void run()

?? {

????? for(int i = 0 ; i < 15; i ++)

????? {

??????? try

??????? {

?????????? Thread.sleep((long)(Math.random()*1000));

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

??????? demo.decrease();

????? }

?? }

}

?

?

?

?

?

?

?

?

?

32.

Object 中最后一個方法—— colone;

首先介紹淺克隆,被克隆的類必須實現了Cloneable接口

該接口是一個標識接口!

克隆的只是對象!

對于任何的拷貝對象X;一定有

1. X.clone() != X;

?? 即克隆的對象與原對象肯定不是一個對象;

1.X.clone().getClass() ==x.getClass();

一個類不管有多少個對象,它們都有著共同的一個類!

2.如果設計的合適的話

x.clone().equals(x)是正確的;

?

下面是淺克隆:

package com.jianjian.clone;

?

public class CloneTest1

{

?? public static void main(String[] args)throws CloneNotSupportedException

?? {

????? Person person = new Person();

????? person.setAge(20);

????? person.setName("yangmanman");

????? Person person1 = (Person)person.clone();//注意到返回的對象是Object類型的,不要忘記類型轉換;

????? System.out.println(person1.getAge());

????? System.out.println(person1.getName());

????? System.out.println(person1 == person);

????? System.out.println(person1.getClass() == person.getClass());

????? System.out.println(person1.equals(person));//我重寫了equals方法;將結果返回true

?? }

}

class Person implements Cloneable

{

?? private int age;

?? private Stringname;

?? public int getAge()

?? {

????? return age;

?? }

?? public void setAge(int age)

?? {

????? this.age = age;

?? }

?? public String getName()

?? {

????? return name;

?? }

?? public void setName(String name)

?? {

????? this.name = name;

?? }

?? @Override//需要重寫clone方法;

?? protected Object clone()throws CloneNotSupportedException

?? {

?????

????? Object object = super.clone();

????? return object;

?????

?? }

?? @Override

?? public int hashCode()

?? {

????? final int prime = 31;

????? int result = 1;

????? result = prime * result + age;

????? result = prime * result + ((name ==null) ? 0 :name.hashCode());

????? return result;

?? }

?? @Override

?? public boolean equals(Object obj)

?? {

????? if (this == obj)

??????? return true;

????? if (obj ==null)

??????? return false;

????? if (getClass() != obj.getClass())

??????? return false;

????? Person other = (Person) obj;

????? if (age != other.age)

??????? return false;

????? if (name ==null)

????? {

??????? if (other.name !=null)

?????????? return false;

????? }

????? else if (!name.equals(other.name))

??????? return false;

????? return true;

?? }

??

??

}

?

33.

關于深克隆,以后深究

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

總結

以上是生活随笔為你收集整理的Java学习笔记十五的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。