當前位置:首頁 » 操作系統 » javautil源碼

javautil源碼

發布時間: 2022-09-06 03:18:19

1. java 源代碼(if語句)

importjava.util.Scanner;

publicclasstest{
publicstaticvoidmain(String[]args){
intj=0;//從0米開始跑
Scannerin=newScanner(System.in);
while(true){
System.out.println("你跑了多少米?");
j=in.nextInt();
System.out.println("口渴嗎?請輸入(yesorno)");
Stringthirst=in.next();
if(j>400){
if(!thirst.equals("yes")){
System.out.println("好吧,那你繼續跑吧!");
continue;//不喝水,繼續跑
}else{
System.out.println("過來喝水吧");
}
break;
}
else{
continue;
}
}
}
}

謝謝採納

2. Java源碼 實現網路爬蟲

//Java爬蟲demo

importjava.io.File;
importjava.net.URL;
importjava.net.URLConnection;
importjava.nio.file.Files;
importjava.nio.file.Paths;
importjava.util.Scanner;
importjava.util.UUID;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;

publicclassDownMM{
publicstaticvoidmain(String[]args)throwsException{
//out為輸出的路徑,注意要以\結尾
Stringout="D:\JSP\pic\java\";
try{
Filef=newFile(out);
if(!f.exists()){
f.mkdirs();
}
}catch(Exceptione){
System.out.println("no");
}

Stringurl="http://www.mzitu.com/share/comment-page-";
Patternreg=Pattern.compile("<imgsrc="(.*?)"");
for(intj=0,i=1;i<=10;i++){
URLuu=newURL(url+i);
URLConnectionconn=uu.openConnection();
conn.setRequestProperty("User-Agent","Mozilla/5.0(WindowsNT6.3;WOW64;Trident/7.0;rv:11.0)likeGecko");
Scannersc=newScanner(conn.getInputStream());
Matcherm=reg.matcher(sc.useDelimiter("\A").next());
while(m.find()){
Files.(newURL(m.group(1)).openStream(),Paths.get(out+UUID.randomUUID()+".jpg"));
System.out.println("已下載:"+j++);
}
}
}
}

3. java求源代碼

你是青鳥的吧這我寫過有源碼這里怎麼上傳壓縮包啊

packageghhh;

importjava.util.Scanner;

publicclassDvD{

publicstaticvoidmain(String[]args){

intstate[]=newint[6];
Stringname[]=newString[6];
intdate[]=newint[6];
intcount[]=newint[6];

name[0]="權利的游戲";
name[1]="命運之夜";
name[2]="傲慢與偏見";

state[0]=1;
state[1]=0;
state[2]=1;

date[0]=13;
date[1]=0;
date[2]=9;

count[0]=23;
count[1]=23;
count[2]=23;
intn;
// booleann=false;
do{
System.out.println("歡迎使用迷你DVD管理器");
System.out.println("1.新增DVD");
System.out.println("2.查看DVD");
System.out.println("3.刪除DVD");
System.out.println("4.借出DVD");
System.out.println("5.歸還DVD");
System.out.println("6.退出DVD");
Scannerinput=newScanner(System.in);
System.out.println("請選擇:");
n=input.nextInt();

switch(n){
case1:
System.out.println("請輸入要增加DVD的名稱:");
Stringname1=input.next();
booleanflag=false;
for(inti=0;i<name.length;i++){
if(name[i]==null){
name[i]=name1;
flag=true;
break;
}
}
if(flag){
System.out.println("新增DVD"+name1+"成功");
}else{
System.out.println("貨架已滿!增加失敗!");
}
System.out.println("請輸入0返回!");
n=input.nextInt();
break;

case2:
System.out.println("序號 "+"狀態 "+"名稱 "+"借出日期 "+"借出次數");

for(inti=0;i<name.length;i++){
if(name[i]!=null){
Stringstate1=((state[i]==0)?"可借":"已借");
Stringdate1=((date[i]==0)?"":date[i]+"日");
Stringcount1=count[i]+"次";
System.out.println((i+1)+" "+state1+" "+name[i]+" "+date1+" "+count1);
}
}

System.out.println("請輸入0返回!");
n=input.nextInt();
break;

case3:
System.out.println("請輸入要刪除的DVD名稱:");
Stringname2=input.next();
intindex=-1;
booleana=false;
booleanflag1=false;
for(inti=0;i<name.length;i++){
if(name2.equals(name[i])&&state[i]==1){
System.out.println("此DVD已經借出,無法刪除");
a=true;
break;
}elseif(name2.equals(name[i])&&state[i]==0){
a=true;
index=i;
flag1=true;
System.out.println("刪除成功!");
break;
}
}
if(a==false){
System.out.println("沒有找到相同名稱的DVD!");
}
if(flag1){
for(inti=index;i<name.length;i++){
if(i!=name.length-1){
name[i]=name[i+1];
state[i]=state[i+1];
date[i]=date[i+1];
count[i]=count[i+1];
}
name[name.length-1]=null;
state[name.length-1]=0;
date[name.length-1]=0;
count[name.length-1]=0;
}
}
System.out.println("請輸入0返回!");
n=input.nextInt();
break;

case4:
System.out.println("請輸入要借出的DVD:");
Stringname3=input.next();
booleana3=false;
booleanb3=false;
for(inti=0;i<name.length;i++){
if(name3.equals(name[i])&&state[i]==1){
System.out.println("該DVD已經借出");
a3=true;
}elseif(name3.equals(name[i])&&state[i]==0){
do{
System.out.println("請輸入借出的日期:");
intm=input.nextInt();

if(m>31||m<1){
System.out.println("請重新輸入日期:");
b3=true;
}else{
date[i]=m;
state[i]=1;
count[i]+=1;
}

}while(b3==true);
System.out.println("借出成功!");
a3=true;
}
}
if(a3==false){
System.out.println("沒有該DVD");
}
System.out.println("請輸入0返回!");
n=input.nextInt();
break;

case5:
System.out.println("請輸入要歸還的DVD:");
Stringname5=input.next();
booleanb5=false;
booleanm5=false;
for(inti=0;i<name.length;i++){
if(name5.equals(name[i])&&state[i]==1){
b5=true;
do{
System.out.println("請輸入要歸還DVD的日期:(歸還日期請輸入當月日期1~31)");
inta5=input.nextInt();
if(a5>31){
System.out.println("請重新輸入日期:");
m5=true;

}elseif(a5<date[i]){
System.out.println("借出日期是"+date[i]+"日 輸入的日期不能小於借出的日期,請重新輸入日期:");
m5=true;
}else{
state[i]=0;
System.out.println("歸還成功");
System.out.println("借出日期是:"+date[i]+"歸還日期是:"+a5+"日 租金一天一元:共"+(a5-date[i])+"元");
date[i]=0;
m5=false;
}

}while(m5==true);


}elseif(name5.equals(name[i])&&state[i]==0){
System.out.println("該DVD未借出,不可歸還!");
b5=true;
}
}

if(b5==false){
System.out.println("沒有該名稱的DVDV");
}

System.out.println("請輸入0返回!");
n=input.nextInt();
break;

case6:
n=1;
System.out.println("程序退出!");
break;

default:
if(n==0){
}else{
System.out.println("輸入錯誤!請重新輸入!");
n=0;
}
break;

}


}while(n==0);

System.out.println("謝謝使用!");
}

}

看看有沒有問題 好久之前的了

4. java 源代碼 基礎點的 謝謝

package com.regex;
import java.io.*;
import java.net.URLDecoder;
import java.util.regex.*;
public class Regex {
private int REMARK=0;
private int LOGIC=0;
private int PHYSIC=0;
boolean start=false;

/**
* @param args
*/
public static void main(String[] args) { //測試方法
// TODO Auto-generated method stub
Regex re=new Regex();
re.regCount("Regex.java");
System.out.println("remark Line: "+re.REMARK);
System.out.println("logic Line: "+re.LOGIC);
System.out.println("physic Line: "+re.PHYSIC);

}/**
* @author BlueDance
* @param s
* @deprecated count
*/
public void regCount(String s){
String url=null;
try {
url=URLDecoder.decode(this.getClass().getResource(s).getPath(),"UTF-8");
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
try {
BufferedReader br=new BufferedReader(new FileReader(new File(url)));
String s1=null;
while((s1=br.readLine())!=null){
PHYSIC++;
if(CheckChar(s1)==1){
REMARK++;
System.out.println("純注釋行:"+s1);
}
if(CheckChar(s1)==2){
LOGIC++;
REMARK++;
System.out.println("非純注釋行:"+s1);
}
if(CheckChar(s1)==3)
LOGIC++;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}

}
/**
*
* @param s
* @return int
* @version check s
*/
public int CheckChar(String s){
String s1=null;
if(s!=null)
s1=s.trim();

//System.out.println(regCheck(s1,re));
if(regCheck(s1,"(//.*)")) //判斷//開頭的為純注釋行
return 1;
if(regCheck(s1,"(.*[;{})] *//.*)")) //判斷不是//開頭的非純注釋行
return 2;
if(regCheck(s1,"(//*.*)")){ //判斷/*開頭的純注釋行
start=true;
return 1;
}
if(regCheck(s1,"(.*[;{})]//*.*)")){ //判斷不是/*開頭的非純注釋行
start=true;
return 2;
}
if(regCheck(s1,"(.* */*/)")){ //判斷*/結尾的純注釋行
start=false;
return 1;
}
if(regCheck(s1,"(.* */*/.*)")&&!strCheck(s1)){ //判斷不是*/結尾的非純注釋行
if(strCheck(s1)){
start=false;
return 2;
}
}
if(start==true) //狀態代碼,start即/*開始時start=true*/結束時為false
return 1;
return 3;//ssssllll
}//aeee
/**
*
* @param s
* @param re
* @return boolean
*/
public boolean regCheck(String s,String re){ //正則表達試判斷方法
return Pattern.matches(re,s);
}
public boolean strCheck(String s){ //中間有*/的字元判斷 此方法最關鍵
if(s.indexOf("*/")>0){
int count=0;
String y[]=s.split("/*/");
boolean boo[]=new boolean[y.length];
for (int i = 0; i < y.length-1; i++) {
char c[]=y[i].toCharArray();
for (int j = 0; j < c.length; j++) {
if(c[j]=='\\'&&c[j+1]=='"'){
count++;
}
}
if(count%2==0){
if(countNumber("\"",y[i])%2!=0){
boo[i]=true;
}else{
boo[i]=false;
}
}else{
if(countNumber("\"",y[i])%2==0){
boo[i]=true;
}else{
boo[i]=false;
}
}

}
for(int i=0;i<boo.length;i++){
if(!boo[i])
return false;
}
return true;
}
return false;
}
public int countNumber(String s,String y){ //此方法為我前面寫的字元串出現次數統計方法,不懂的可以看我前面的文章
int count=0;
String [] k=y.split(s);
if(y.lastIndexOf(s)==(y.length()-s.length()))
count=k.length;
else
count=k.length-1;
if(count==0)
System.out.println ("字元串\""+s+"\"在字元串\""+y+"\"沒有出現過");
else
return count;
return -1;
}

}

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GoodLucky extends JFrame implements ActionListener{

JTextField tf = new JTextField(); //實例化一個文本域
//設置兩個按鈕
JButton b1 = new JButton("開始");
JButton b2 = new JButton("停止");
boolean isGo = false;
//構造函數
public GoodLucky(){
b1.setActionCommand("start");//在開始按鈕上設置一個動作監聽 start
JPanel p = new JPanel(); //實例化一個可視化容器
//將兩個按鈕添加到可視化容器上面,用add方法
p.add(b1);
p.add(b2);
//在兩個按鈕上增加監聽的屬性,自動調用下面的監聽處理方法actionPerformed(ActionEvent e),如果要代碼有更好的可讀性,可用內部類實現動作
//監聽處理。
b1.addActionListener(this);
b2.addActionListener(this);
//將停止按鈕設置為不可編輯(即不可按的狀態)
b2.setEnabled(false);

this.getContentPane().add(tf,"North"); //將上面的文本域放在面板的北方,也就是上面(上北下南左西右東)
this.getContentPane().add(p,"South"); //將可視化容器pannel放在南邊,也就是下面
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //設置用戶在此窗體上發起 "close" 時默認執行的操作,參數EXIT_ON_CLOSE是使用 System exit 方法退出應用程序。僅在應用程序中使用

this.setSize(300,200); //設置面板大小,寬和高
this.setLocation(300,300); //設置面板剛開始的出現的位置
Cursor cu = new Cursor(Cursor.HAND_CURSOR); //用指定名稱創建一個新的定製游標對象,參數表示手狀游標類型
this.setCursor(cu); //為指定的游標設置游標圖像,即設置游標圖像為上面所創建的手狀游標類型
this.setVisible(true); //將面板可視化設置為true,即可視,如果為false,即程序運行時面板會隱藏
tf.setText("welcome you! "); //設置面板的標題為歡迎
this.go(); //調用go方法

}

public void go(){
while(true){ //這里是死循環,也就是說用戶不點擊停止按鈕的話他一直循環出現隨機數,直到用戶點擊停止按鈕循環才能推出,具體流程在actionPerformed方法中控制。
if(isGo == true){ //上面所定義的isGo的初始值為false,所以程序第一次到此會跳過
String s = ""; //設置空字元串
for(int j = 1; j <= 7;j++){ //產生7個隨機數
int i = (int)(Math.random() * 36) + 1;//每個隨機數產生方式,這里定義靈活,可以自由定義隨機數產生的方式
if(i < 10){
s = s + " 0" + i; //如果產生的隨機數小於10的話做處理:這里就牽扯到一個重要的概念,簡單敘述一下:
/*
當一個字元串與一個整型數項相加的意思是連接,上面的s = s + " 0" + i的意思是字元串s鏈接0再連接整型i值,而不會導致0和整型的i相加,
產生的效果為s0i,由於s為空字元串(上面定義過的),所以當i小於零時,在個位數前面加上0,比如產生的隨機數i為7的話,顯示效果為 07.
*/
}else{
s = s + " " + i; //如果產生的隨機數比10打的話,那麼加上空格顯示,即數字和數字之間有個空格
}
//以上循環循環七次,以保證能出現7個隨機數
}
tf.setText(s); //將產生的隨機數全部顯示在文本域上,用文本域對象tf調用它的設置文本的方法setText(String)實現。
}

//以下為線程延遲
try{
Thread.sleep(10); //線程類同步方法sleep,睡眠方法,括弧里的單位為ms。
}catch(java.lang.InterruptedException e){
e.printStackTrace(); //異常捕獲,不用多說。
}

}

}

//以下是上面設置的事件監聽的具體處理辦法,即監聽時間處理方法,自動調用
public void actionPerformed(ActionEvent e){ //傳入一個動作事件的參數e
String s = e.getActionCommand(); //設置字元串s來存儲獲得動作監聽,上面的start
/*
以下這個條件語句塊的作用為:用戶點擊開始後(捕獲start,用方法getActionCommand()),將命令觸發設置為true,從而執行上面的go方法中的循環體(因為循環體中要求isGo參數為true,而初始為false)。
執行循環快產生隨機數,並將開始按鈕不可編輯化,而用戶只可以使用停止按鈕去停止。如果用戶按下停止時,也就是沒有傳入參數「start」的時候,
執行else語句塊中的語句,isGo設置為false,將不執行上面go中的循環語句塊,從而停止產生隨機數,並顯示,並且把開始按鈕設置為可用,而把
停止按鈕設置為不可用,等待用戶按下開始再去開始新一輪循環產生隨機數。
*/
if(s.equals("start")){ //如果捕獲到start,也就是用戶觸發了動作監聽器,那麼下面處理
isGo = true; //設置isGo為true
b1.setEnabled(false); //將開始按鈕設置為不可用
b2.setEnabled(true); //將停止按鈕設置為可用
}else{
isGo = false; //將isGo設置為false,isGo為循環標志位
b2.setEnabled(false); //設置停止按鈕為不可用(注意看是b2,b2是停止按鈕)
b1.setEnabled(true); //設置開始按鈕為可用
}

}

public static void main(String[] args){
new GoodLucky(); //產生類的實例,執行方法
}
}

5. java.util包的源碼

在你安裝的jdk中就有, 比如我的就在:
C:\Program Files\Java\jdk1.6.0_05\src.zip

6. java並發包源碼怎麼讀

1. 各種同步控制工具的使用

1.1 ReentrantLock

ReentrantLock感覺上是synchronized的增強版,synchronized的特點是使用簡單,一切交給JVM去處理,但是功能上是比較薄弱的。在JDK1.5之前,ReentrantLock的性能要好於synchronized,由於對JVM進行了優化,現在的JDK版本中,兩者性能是不相上下的。如果是簡單的實現,不要刻意去使用ReentrantLock。

相比於synchronized,ReentrantLock在功能上更加豐富,它具有可重入、可中斷、可限時、公平鎖等特點。

首先我們通過一個例子來說明ReentrantLock最初步的用法:

package test;

import java.util.concurrent.locks.ReentrantLock;public class Test implements Runnable{ public static ReentrantLock lock = new ReentrantLock(); public static int i = 0;

@Override public void run() { for (int j = 0; j < 10000000; j++)
{ lock.lock(); try
{
i++;
} finally
{ lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
Test test = new Test();
Thread t1 = new Thread(test);
Thread t2 = new Thread(test);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}

}

有兩個線程都對i進行++操作,為了保證線程安全,使用了ReentrantLock,從用法上可以看出,與synchronized相比,ReentrantLock就稍微復雜一點。因為必須在finally中進行解鎖操作,如果不在finally解鎖,有可能代碼出現異常鎖沒被釋放,而synchronized是由JVM來釋放鎖。

那麼ReentrantLock到底有哪些優秀的特點呢?

1.1.1 可重入

單線程可以重復進入,但要重復退出

lock.lock();
lock.lock();try{
i++;

}
finally{
lock.unlock();
lock.unlock();
}

由於ReentrantLock是重入鎖,所以可以反復得到相同的一把鎖,它有一個與鎖相關的獲取計數器,如果擁有鎖的某個線程再次得到鎖,那麼獲取計數器就加1,然後鎖需要被釋放兩次才能獲得真正釋放(重入鎖)。這模仿了synchronized的語義;如果線程進入由線程已經擁有的監控器保護的 synchronized 塊,就允許線程繼續進行,當線程退出第二個(或者後續)synchronized塊的時候,不釋放鎖,只有線程退出它進入的監控器保護的第一個synchronized塊時,才釋放鎖。

public class Child extends Father implements Runnable{ final static Child child = new Child();//為了保證鎖唯一
public static void main(String[] args) { for (int i = 0; i < 50; i++) { new Thread(child).start();
}
}
public synchronized void doSomething() {
System.out.println("1child.doSomething()");
doAnotherThing(); // 調用自己類中其他的synchronized方法
}
private synchronized void doAnotherThing() { super.doSomething(); // 調用父類的synchronized方法
System.out.println("3child.doAnotherThing()");
}
@Override
public void run() {
child.doSomething();
}
}class Father { public synchronized void doSomething() {
System.out.println("2father.doSomething()");
}
}

我們可以看到一個線程進入不同的synchronized方法,是不會釋放之前得到的鎖的。所以輸出還是順序輸出。所以synchronized也是重入鎖

輸出:

1child.doSomething()
2father.doSomething()
3child.doAnotherThing()
1child.doSomething()
2father.doSomething()
3child.doAnotherThing()
1child.doSomething()
2father.doSomething()
3child.doAnotherThing()
...

1.1.2.可中斷

與synchronized不同的是,ReentrantLock對中斷是有響應的。中斷相關知識查看[高並發Java 二] 多線程基礎

普通的lock.lock()是不能響應中斷的,lock.lockInterruptibly()能夠響應中斷。

我們模擬出一個死鎖現場,然後用中斷來處理死鎖

package test;import java.lang.management.ManagementFactory;import java.lang.management.ThreadInfo;import java.lang.management.ThreadMXBean;import java.util.concurrent.locks.ReentrantLock;public class Test implements Runnable{ public static ReentrantLock lock1 = new ReentrantLock(); public static ReentrantLock lock2 = new ReentrantLock(); int lock; public Test(int lock)
{ this.lock = lock;
} @Override
public void run()
{ try
{ if (lock == 1)
{
lock1.lockInterruptibly(); try
{
Thread.sleep(500);
} catch (Exception e)
{ // TODO: handle exception
}
lock2.lockInterruptibly();
} else
{
lock2.lockInterruptibly(); try
{
Thread.sleep(500);
} catch (Exception e)
{ // TODO: handle exception
}
lock1.lockInterruptibly();
}
} catch (Exception e)
{ // TODO: handle exception
} finally
{ if (lock1.isHeldByCurrentThread())
{
lock1.unlock();
} if (lock2.isHeldByCurrentThread())
{
lock2.unlock();
}
System.out.println(Thread.currentThread().getId() + ":線程退出");
}
} public static void main(String[] args) throws InterruptedException {
Test t1 = new Test(1);
Test t2 = new Test(2);
Thread thread1 = new Thread(t1);
Thread thread2 = new Thread(t2);
thread1.start();
thread2.start();
Thread.sleep(1000); //DeadlockChecker.check();
} static class DeadlockChecker
{ private final static ThreadMXBean mbean = ManagementFactory
.getThreadMXBean(); final static Runnable deadlockChecker = new Runnable()
{ @Override
public void run()
{ // TODO Auto-generated method stub
while (true)
{ long[] deadlockedThreadIds = mbean.findDeadlockedThreads(); if (deadlockedThreadIds != null)
{
ThreadInfo[] threadInfos = mbean.getThreadInfo(deadlockedThreadIds); for (Thread t : Thread.getAllStackTraces().keySet())
{ for (int i = 0; i < threadInfos.length; i++)
{ if(t.getId() == threadInfos[i].getThreadId())
{
t.interrupt();
}
}
}
} try
{
Thread.sleep(5000);
} catch (Exception e)
{ // TODO: handle exception
}
}

}
};
public static void check()
{
Thread t = new Thread(deadlockChecker);
t.setDaemon(true);
t.start();
}
}

}

上述代碼有可能會發生死鎖,線程1得到lock1,線程2得到lock2,然後彼此又想獲得對方的鎖。

我們用jstack查看運行上述代碼後的情況

下面舉個例子:

package test;import java.util.concurrent.CyclicBarrier;public class Test implements Runnable{ private String soldier; private final CyclicBarrier cyclic; public Test(String soldier, CyclicBarrier cyclic)
{ this.soldier = soldier; this.cyclic = cyclic;
} @Override
public void run()
{ try
{ //等待所有士兵到齊
cyclic.await();
dowork(); //等待所有士兵完成工作
cyclic.await();
} catch (Exception e)
{ // TODO Auto-generated catch block
e.printStackTrace();
}

} private void dowork()
{ // TODO Auto-generated method stub
try
{
Thread.sleep(3000);
} catch (Exception e)
{ // TODO: handle exception
}
System.out.println(soldier + ": done");
} public static class BarrierRun implements Runnable
{ boolean flag; int n; public BarrierRun(boolean flag, int n)
{ super(); this.flag = flag; this.n = n;
} @Override
public void run()
{ if (flag)
{
System.out.println(n + "個任務完成");
} else
{
System.out.println(n + "個集合完成");
flag = true;
}

}

} public static void main(String[] args)
{ final int n = 10;
Thread[] threads = new Thread[n]; boolean flag = false;
CyclicBarrier barrier = new CyclicBarrier(n, new BarrierRun(flag, n));
System.out.println("集合"); for (int i = 0; i < n; i++)
{
System.out.println(i + "報道");
threads[i] = new Thread(new Test("士兵" + i, barrier));
threads[i].start();
}
}

}

列印結果:

集合

士兵5: done士兵7: done士兵8: done士兵3: done士兵4: done士兵1: done士兵6: done士兵2: done士兵0: done士兵9: done10個任務完成

1.7 LockSupport

提供線程阻塞原語

和suspend類似

LockSupport.park();
LockSupport.unpark(t1);

與suspend相比不容易引起線程凍結

LockSupport的思想呢,和Semaphore有點相似,內部有一個許可,park的時候拿掉這個許可,unpark的時候申請這個許可。所以如果unpark在park之前,是不會發生線程凍結的。

下面的代碼是[高並發Java 二] 多線程基礎中suspend示例代碼,在使用suspend時會發生死鎖。

而使用LockSupport則不會發生死鎖。

另外

park()能夠響應中斷,但不拋出異常。中斷響應的結果是,park()函數的返回,可以從Thread.interrupted()得到中斷標志。

在JDK當中有大量地方使用到了park,當然LockSupport的實現也是使用unsafe.park()來實現的。

public static void park() { unsafe.park(false, 0L);
}

1.8 ReentrantLock 的實現

下面來介紹下ReentrantLock的實現,ReentrantLock的實現主要由3部分組成:

  • CAS狀態

  • 等待隊列

  • park()

  • ReentrantLock的父類中會有一個state變數來表示同步的狀態

  • /**

  • * The synchronization state.

  • */

  • private volatile int state;

  • 通過CAS操作來設置state來獲取鎖,如果設置成了1,則將鎖的持有者給當前線程

  • final void lock() { if (compareAndSetState(0, 1))

  • setExclusiveOwnerThread(Thread.currentThread()); else

  • acquire(1);

  • }

  • 如果拿鎖不成功,則會做一個申請

  • public final void acquire(int arg) { if (!tryAcquire(arg) &&

  • acquireQueued(addWaiter(Node.EXCLUSIVE), arg))

  • selfInterrupt();

  • }

  • 首先,再去申請下試試看tryAcquire,因為此時可能另一個線程已經釋放了鎖。

    如果還是沒有申請到鎖,就addWaiter,意思是把自己加到等待隊列中去

    其間還會有多次嘗試去申請鎖,如果還是申請不到,就會被掛起

  • private final boolean parkAndCheckInterrupt() {

  • LockSupport.park(this); return Thread.interrupted();

  • }

  • 同理,如果在unlock操作中,就是釋放了鎖,然後unpark,這里就不具體講了。

    2. 並發容器及典型源碼分析

    2.1ConcurrentHashMap

    我們知道HashMap不是一個線程安全的容器,最簡單的方式使HashMap變成線程安全就是使用Collections.synchronizedMap,它是對HashMap的一個包裝

  • public static Map m=Collections.synchronizedMap(new HashMap());

  • 同理對於List,Set也提供了相似方法。

    但是這種方式只適合於並發量比較小的情況。

    我們來看下synchronizedMap的實現

    它會將HashMap包裝在裡面,然後將HashMap的每個操作都加上synchronized。

    由於每個方法都是獲取同一把鎖(mutex),這就意味著,put和remove等操作是互斥的,大大減少了並發量。

    下面來看下ConcurrentHashMap是如何實現的

    在ConcurrentHashMap內部有一個Segment段,它將大的HashMap切分成若干個段(小的HashMap),然後讓數據在每一段上Hash,這樣多個線程在不同段上的Hash操作一定是線程安全的,所以只需要同步同一個段上的線程就可以了,這樣實現了鎖的分離,大大增加了並發量。

    在使用ConcurrentHashMap.size時會比較麻煩,因為它要統計每個段的數據和,在這個時候,要把每一個段都加上鎖,然後再做數據統計。這個就是把鎖分離後的小小弊端,但是size方法應該是不會被高頻率調用的方法。

    在實現上,不使用synchronized和lock.lock而是盡量使用trylock,同時在HashMap的實現上,也做了一點優化。這里就不提了。

    2.2BlockingQueue

    BlockingQueue不是一個高性能的容器。但是它是一個非常好的共享數據的容器。是典型的生產者和消費者的實現。

7. 求Java 日歷的小程序的源代碼

當在一段代碼塊定義一個變數時,Java就在棧中 為這個變數分配內存空間,當該變數退出該作用域後,Java會自動釋放掉為該變數所分配的內存空間,該內存空間可以立即被另作他用。

Java內存分配中的堆

堆內存用來存放由new創建的對象和數組。 在堆中分配的內存,由Java虛擬機的自動垃圾回收器來管理。

8. java.util.* 這一類的包在哪裡能查看其內容和作用。

java.io包是java處理輸入輸出的包,裡面有各種用於讀寫數據的類。
java.util包是java的使用工具包,包括java提供給我們的各種使用工具類。
具體內容你可以看java官方API文檔:https://docs.oracle.com/javase/8/docs/api/index.html,
進入後,你在左上角的Package那個框里選io或者util,下面那個框里就會列出這個包里所有介面、類和異常,你想具體看那個就點那個,右邊那個框裡面就會有詳細的介紹。

9. java.util API 研究問題

1 你可能會發現有類庫里的類 extends 了Object,這是不是多餘呢?
這么做是為了長遠的打算,現在是沒什麼用,將來有沒有用,我也不知道

2.AbstractCollection 是支持泛型的,泛型不能用來定義數組,但可以使用反射API創建數組

3.這肯定是不一樣的,如果一樣就完了,他有專門的沖突解決辦法,方法有很多種,例如線性探索、平方探索、二次哈希等,HashMap具體採用的那一種我沒研究過

10. 什麼是java源代碼 怎麼查看

不知道你說的是瀏覽器的還是什麼的,
如果是瀏覽器的那麼簡單找到工具-查看源代碼,你就能看見代碼了,
還有一個就是被編譯成class文件的java用反編譯工具可以看到源代碼,
如果以上都不是你想要的答案,那麼你所說的代碼就是程序員寫好的代碼文件

熱點內容
鏈數據存儲 發布:2024-05-12 22:26:41 瀏覽:426
android的web應用 發布:2024-05-12 22:19:00 瀏覽:170
如何反編譯vfp 發布:2024-05-12 22:16:30 瀏覽:746
在瀏覽器內訪問ftp服務數據 發布:2024-05-12 22:07:48 瀏覽:954
編程是 發布:2024-05-12 21:54:40 瀏覽:484
編程補習班 發布:2024-05-12 21:52:10 瀏覽:468
mapreduce緩存 發布:2024-05-12 21:43:30 瀏覽:928
易譜加密狗 發布:2024-05-12 21:43:30 瀏覽:327
傳奇世界飛天腳本 發布:2024-05-12 21:34:41 瀏覽:377
萬聯證券密碼沒改為什麼提示錯誤 發布:2024-05-12 21:34:02 瀏覽:599