導航:首頁 > 源碼編譯 > go語言flag包源碼

go語言flag包源碼

發布時間:2024-02-28 16:13:49

A. 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部分組成:

B. 寫命令行應用程序什麼不可或缺Go可以這樣處理命令行參數

Go語言內置的flag包實現了命令行參數的解析,flag包使得開發命令行工具更為簡單。

如果你只是簡單的想要獲取命令行參數,可以像下面的代碼示例一樣使用os.Args來獲取命令行參數。

將上面的代碼執行go build -o "args_demo"編譯之後,執行:

os.Args是一個存儲命令行參數的字元串切片,它的第一個元素是執行文件的名稱。

本文介紹了flag包的常用函數和基本用法,更詳細的內容請查看官方文檔。

flag包支持的命令行參數類型有bool、int、int64、uint、uint64、float float64、string、ration。

有以下兩種常用的定義命令行flag參數的方法。

基本格式如下:

flag.Type(flag名, 默認值, 幫助信息)*Type 例如我們要定義姓名、年齡、婚否三個命令行參數,我們可以按如下方式定義:

需要注意的是,此時name、age、married、delay均為對應類型的指針。

基本格式如下: flag.TypeVar(Type指針, flag名, 默認值, 幫助信息) 例如我們要定義姓名、年齡、婚否三個命令行參數,我們可以按如下方式定義:

通過以上兩種方法定義好命令行flag參數後,需要通過調用flag.Parse()來對命令行參數進行解析。

支持的命令行參數格式有以下幾種:

其中,布爾類型的參數必須使用等號的方式指定。

Flag解析在第一個非flag參數(單個」-「不是flag參數)之前停止,或者在終止符」–「之後停止。

定義

使用

命令行參數使用提示:

$ ./flag_demo -help

Usage of ./flag_demo:

-age int

年齡 (default 18)

-d ration

時間間隔

-married

婚否

-name string

姓名 (default "張三")

正常使用命令行flag參數:

使用非flag命令行參數:

原文鏈接:https://www.liwenzhou.com/posts/Go/go_flag/

C. 跪求JAVA五子棋源代碼

很sb的電腦五子棋:
import java.io.*;
import java.util.*;

public class Gobang {
// 定義一個二維數組來充當棋盤
private String[][] board;
// 定義棋盤的大小
private static int BOARD_SIZE = 15;

public void initBoard() {
// 初始化棋盤數組
board = new String[BOARD_SIZE][BOARD_SIZE];
// 把每個元素賦為"╋",用於在控制台畫出棋盤
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
// windows是一行一行來列印的。坐標值為(行值, 列值)
board[i][j] = "╋";
}
}
}

// 在控制台輸出棋盤的方法
public void printBoard() {
// 列印每個數組元素
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
// 列印數組元素後不換行
System.out.print(board[i][j]);
}
// 每列印完一行數組元素後輸出一個換行符
System.out.print("\n");
}
}

// 該方法處理電腦下棋:隨機生成2個整數,作為電腦下棋的坐標,賦給board數組。
private void compPlay() {
// 構造一個隨機數生成器
Random rnd = new Random();
// Random類的nextInt(int n))方法:隨機地生成並返回指定范圍中的一個 int 值,
// 即:在此隨機數生成器序列中 0(包括)和 n(不包括)之間均勻分布的一個int值。
int compXPos = rnd.nextInt(15);
int compYPos = rnd.nextInt(15);
// 保證電腦下的棋的坐標上不能已經有棋子(通過判斷對應數組元素只能是"╋"來確定)
while (board[compXPos][compYPos].equals("╋") == false) {
compXPos = rnd.nextInt(15);
compYPos = rnd.nextInt(15);
}
System.out.println(compXPos);
System.out.println(compYPos);
// 把對應的數組元素賦為"○"。
board[compXPos][compYPos] = "○";
}

// 該方法用於判斷勝負:進行四次循環掃描,判斷橫、豎、左斜、右斜是否有5個棋連在一起
private boolean judgeWin() {
// flag表示是否可以斷定贏/輸
boolean flag = false;
// joinEle:將每一個橫/豎/左斜/右斜行中的元素連接起來得到的一個字元串
String joinEle;
// 進行橫行掃描
for (int i = 0; i < BOARD_SIZE; i++) {
// 每掃描一行前,將joinEle清空
joinEle = "";
for (int j = 0; j < BOARD_SIZE; j++) {
joinEle += board[i][j];
}
// String類的contains方法:當且僅當該字元串包含指定的字元序列時,返回true。
if (joinEle.contains("●●●●●")) {
System.out.println("您贏啦!");
flag = true;
// 停止往下繼續執行,提前返回flag。
// 如果執行了這個return,就直接返回該方法的調用處;
// 不會再執行後面的任何語句,包括最後那個return語句。
// (而break僅僅是完全跳出這個for循環,還會繼續執行下面的for循環。)
return flag;
} else if (joinEle.contains("○○○○○")) {
System.out.println("您輸啦!");
flag = true;
// 提前返回flag
return flag;
}
}
// 進行豎行掃描
for (int i = 0; i < BOARD_SIZE; i++) {
joinEle = "";
for (int j = 0; j < BOARD_SIZE; j++) {
// 豎行的元素是它們的列值相同
joinEle += board[j][i];
}
if (joinEle.contains("●●●●●")) {
System.out.println("您贏啦!");
flag = true;
return flag;
} else if (joinEle.contains("○○○○○")) {
System.out.println("您輸啦!");
flag = true;
return flag;
}
}
// 進行左斜行掃描
for (int i = -(BOARD_SIZE - 2); i < BOARD_SIZE - 1; i++) {
joinEle = "";
for (int j = 0; j < BOARD_SIZE; j++) {
int line = i + j;
// 只截取坐標值沒有越界的點
if (line >= 0 && line < 15) {
joinEle += board[j][line];
}
}
if (joinEle.contains("●●●●●")) {
System.out.println("您贏啦!");
flag = true;
return flag;
} else if (joinEle.contains("○○○○○")) {
System.out.println("您輸啦!");
flag = true;
return flag;
}
}
// 進行右斜行掃描
for (int i = 1; i < 2 * (BOARD_SIZE - 1); i++) {
joinEle = "";
for (int j = 0; j < BOARD_SIZE; j++) {
int line = i - j;
if (line >= 0 && line < 15) {
joinEle += board[j][line];
}
}
if (joinEle.contains("●●●●●")) {
System.out.println("您贏啦!");
flag = true;
return flag;
} else if (joinEle.contains("○○○○○")) {
System.out.println("您輸啦!");
flag = true;
// 最後這個return可省略
}
}
// 確保該方法有返回值(如果上面條件都不滿足時)
return flag;
}

public static void main(String[] args) throws Exception, IOException {
Gobang gb = new Gobang();
gb.initBoard();
gb.printBoard();
// BufferedReader類:帶緩存的讀取器————從字元輸入流中讀取文本,並緩存字元。可用於高效讀取字元、數組和行。
// 最好用它來包裝所有其 read() 操作可能開銷很高的 Reader(如 FileReader 和 InputStreamReader)。
// 下面構造一個讀取器對象。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 定義輸入字元串
String inputStr = null;
// br.readLine():每當在鍵盤上輸入一行內容按回車,剛輸入的內容將被br(讀取器對象)讀取到。
// BufferedReader類的readLine方法:讀取一個文本行。
// 初始狀態由於無任何輸入,br.readLine()會拋出異常。因而main方法要捕捉異常。
while ((inputStr = br.readLine()) != null) {
// 將用戶輸入的字元串以逗號(,)作為分隔符,分隔成2個字元串。
// String類的split方法,將會返回一個拆分後的字元串數組。
String[] posStrArr = inputStr.split(",");
// 將2個字元串轉換成用戶下棋的坐標
int xPos = Integer.parseInt(posStrArr[0]);
int yPos = Integer.parseInt(posStrArr[1]);
// 校驗用戶下棋坐標的有效性,只能是數字,不能超出棋盤范圍
if (xPos > 15 || xPos < 1 || yPos > 15 || yPos < 1) {
System.out.println("您下棋的坐標值應在1到15之間,請重新輸入!");
continue;
}
// 保證用戶下的棋的坐標上不能已經有棋子(通過判斷對應數組元素只能是"╋"來確定)
// String類的equals方法:比較字元串和指定對象是否相等。結果返回true或false。
if (gb.board[xPos - 1][yPos - 1].equals("╋")) {
// 把對應的數組元素賦為"●"。
gb.board[xPos - 1][yPos - 1] = "●";
} else {
System.out.println("您下棋的點已有棋子,請重新輸入!");
continue;
}
// 電腦下棋
gb.compPlay();
gb.printBoard();
// 每次下棋後,看是否可以斷定贏/輸了
if (gb.judgeWin() == false) {
System.out.println("請輸入您下棋的坐標,應以x,y的格式:");
} else {
// 完全跳出這個while循環,結束下棋
break;
}
}
}
}

D. 怎麼卸載源碼編譯安裝的軟體

第一,看大家安裝軟體的時候有沒有使用--prefix這個命令,如果有那就把你指定的文件給刪除了就行了,
第二,如果沒有用這個信念指定就麻煩一點了,那就進入到軟體解壓後的目錄,執行sudo make uninstall看能否成功,
第三,如果不行,那就進入用 editor 查看 makefile 文件 看看裡面卸載的命令是什麼如果該源碼包沒有提供
此類方法刪除 就只能手動刪除
第四,手動刪除最無奈的辦法能不能搞干凈也只能看運氣了,使用whereis xxx 找到軟體安裝目錄,rm -rf 把
這些目錄都刪除,應該能刪除干凈,如whereis python,例子如下:
whereis python
python: /usr/bin/python2.6-config /usr/bin/python2.6 /usr/bin/python /usr/lib/python2.6 /usr/lib64/python2.6 /usr/local/bin/python3.3m-config /usr/local/bin/python3.3m /usr/local/bin/python3.3 /usr/local/bin/python3.3-config /usr/local/lib/python3.3 /usr/include/python2.6 /usr/share/man/man1/python.1.gz
rm -rf /usr/bin/python2.6-config
rm -rf /usr/bin/python2.6
rm -rf /usr/bin/python
rm -rf /usr/lib/python2.6
rm -rf /usr/lib64/python2.6
...................等等,,,
好了,文法就這些吧,如果大家有更好的方法可以評論補充,禁止吐糟,加水。

閱讀全文

與go語言flag包源碼相關的資料

熱點內容
sybaseisql命令 瀏覽:181
android權威編程指南pdf 瀏覽:661
哪些軟體屬於加密軟體 瀏覽:644
文件夾75絲什麼意思 瀏覽:468
最便宜sop8單片機 瀏覽:964
圖解周易預測學pdf 瀏覽:418
c盤莫名奇妙多了幾個文件夾 瀏覽:169
貴州花溪門票優惠app哪個好 瀏覽:801
如何說話不會讓人有被命令的感覺 瀏覽:438
哪裡可下載湘工惠app 瀏覽:263
福特python 瀏覽:310
pdf轉換成word表格 瀏覽:351
無線遠端伺服器無響應是什麼意思 瀏覽:670
兩位整數倒序輸出python 瀏覽:781
為什麼我的世界天空伺服器進不去 瀏覽:262
釘釘直播後的視頻如何線上加密 瀏覽:503
聽主的命令 瀏覽:208
全民上雲時代雲伺服器 瀏覽:519
iphone不創建id如何下載app 瀏覽:972
windowsphp擴展安裝 瀏覽:93