The import XXX conflicts with a type defined in the same file
假設新增一個 java 檔,檔名叫 List,那麼使用到 java 內鍵的List時,假設是 java.util.List 時,import 時就會出現這個錯
解決方法是使用package.class名稱,就不要 import 了,如java.util.List<String> list = new ArrayList<>();
假設檔名叫 Test.java,那麼使用 junit 的 @Test 時也要全部打,不要 import 了,如 @org.junit.Test
以上就算自己新建的檔案有 package 名稱,一樣會出這個錯
2017年3月21日 星期二
2017年3月15日 星期三
增加ORCL
做完此篇的動作,即可使用PL/SQL Developer
安裝完 Oracle 後,ORCL 的路徑在 app\BAU\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora
想增加可用Net Manager
1.在程式集可看到如下的畫面

2.選到Service Naming 後,按旁邊綠色的加號,名字是待會在PL/SQL Developer 登入時的 Database 欄位會出現的 (做完後Service Naming下也會出現)

3.選預設的即可

4.這IP要和專案的人要

5.Service Name 也是要和專案的人要,如 192.168.11.22:1521:xxx 裡的xxx

6.不放心可按 Test... 測試一下,有自信就直接按 Finish 了

7.如果第 6 步是選 Test...,就會看到這個畫面,按 Change Login...,可用帳號密碼測試

按下完成後,會在app\BAU\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora 裡的內容發現已經增加了
安裝完 Oracle 後,ORCL 的路徑在 app\BAU\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora
想增加可用Net Manager
1.在程式集可看到如下的畫面

2.選到Service Naming 後,按旁邊綠色的加號,名字是待會在PL/SQL Developer 登入時的 Database 欄位會出現的 (做完後Service Naming下也會出現)

3.選預設的即可

4.這IP要和專案的人要

5.Service Name 也是要和專案的人要,如 192.168.11.22:1521:xxx 裡的xxx

6.不放心可按 Test... 測試一下,有自信就直接按 Finish 了

7.如果第 6 步是選 Test...,就會看到這個畫面,按 Change Login...,可用帳號密碼測試

按下完成後,會在app\BAU\product\11.2.0\dbhome_1\NETWORK\ADMIN\tnsnames.ora 裡的內容發現已經增加了
Linux 的連結和 Windows 的 mklink
不管是Linux 還 Windows ,連結檔的容量都是很小的
1.將一個檔案硬連結和多個檔案以後,假設是5個,刪除其中1~4個不會影響本來的檔案
2.只能是同一個檔案系統
3.inode 一樣
4.只能操作檔案
5.ls -l 查看時,第一個並不是L,是-
1.目的檔案若被刪除,則來源會出現錯誤
2.可跨越不同的檔案系統
3.inode 不同
4.ls -l 查看時,是 L
5.-s = --symbolic
還有一個參數 f,意思是如果目的檔已經有了,會先刪除再新增
mklink [/H /S /J] 檔案或目錄名稱 已有的檔案或目錄名稱
先切換到想連結的地方,然後如下操作
1.只對檔案有效,如果目的為目錄,會出現「存取被拒」
2.也只能在同個槽才行,如 C 槽不能到 D 槽
針對檔案:mklink <來源> <目的>,如果目的為目錄會成功,但沒作用,無意義
針對目錄:mklink -d <來源> <目的>,如果目的為檔案會成功,但點下去會報錯,無意義
但只能使用在目錄
語法:mklink -j <來源> <目的>,目的為檔案會成功,但點下去會報錯,無意義
2.使用 dir 指令時,軟連結是<SYMLINK>,NTFS 連結是<JUNCTION>
3.複製時不同,將這兩個連結複製到其他的目錄後
.軟連結只有原本的目錄才可以連
.NTFS 連結無法複製,複製完後到目的資料夾貼上時,沒有作用
4.移動時不同,將這兩個連結剪下到其他的目錄貼上後
.軟連結真的會移動,也可連結
.NTFS 連結會複製一份到新的目錄,原本的還可以連結,但複製後的不行
※注意 NTFS 連結還會將原本目錄的所有檔案、目錄全部移動到新的目錄,造成原本的目錄 是空的情形,此時所有連結裡面都是空的
Linux
ln [-s] 已有的檔案或目錄名稱 檔案或目錄名稱硬連結
語法:ln <目的> <來源>1.將一個檔案硬連結和多個檔案以後,假設是5個,刪除其中1~4個不會影響本來的檔案
2.只能是同一個檔案系統
3.inode 一樣
4.只能操作檔案
5.ls -l 查看時,第一個並不是L,是-
軟連結
語法:ln -s <目的> <來源>1.目的檔案若被刪除,則來源會出現錯誤
2.可跨越不同的檔案系統
3.inode 不同
4.ls -l 查看時,是 L
5.-s = --symbolic
還有一個參數 f,意思是如果目的檔已經有了,會先刪除再新增
Windows
以下是用Windows 7 的實驗,必需有管理的權限來操作,而且來源的檔案或目錄不可存在mklink [/H /S /J] 檔案或目錄名稱 已有的檔案或目錄名稱
先切換到想連結的地方,然後如下操作
硬連結(Hard)
語法:mklink -h <來源> <目的>1.只對檔案有效,如果目的為目錄,會出現「存取被拒」
2.也只能在同個槽才行,如 C 槽不能到 D 槽
軟連結(Symbolic/Soft)
語法:針對檔案:mklink <來源> <目的>,如果目的為目錄會成功,但沒作用,無意義
針對目錄:mklink -d <來源> <目的>,如果目的為檔案會成功,但點下去會報錯,無意義
NTFS 連結(Junction)
故名思義,檔案系統是NTFS才可使用,在X槽按右鍵-->屬性的一般活頁標籤可看到但只能使用在目錄
語法:mklink -j <來源> <目的>,目的為檔案會成功,但點下去會報錯,無意義
軟連結的目錄和 NTFS 連結的差異
1.右鍵屬性時,軟連結會多一個 Shortcut 的活頁標籤2.使用 dir 指令時,軟連結是<SYMLINK>,NTFS 連結是<JUNCTION>
3.複製時不同,將這兩個連結複製到其他的目錄後
.軟連結只有原本的目錄才可以連
.NTFS 連結無法複製,複製完後到目的資料夾貼上時,沒有作用
4.移動時不同,將這兩個連結剪下到其他的目錄貼上後
.軟連結真的會移動,也可連結
.NTFS 連結會複製一份到新的目錄,原本的還可以連結,但複製後的不行
※注意 NTFS 連結還會將原本目錄的所有檔案、目錄全部移動到新的目錄,造成原本的目錄 是空的情形,此時所有連結裡面都是空的
2017年3月8日 星期三
ExecutorService (Thread 六)
連線到資料庫有個連線池,Thread 也有 Thread pool ,ExecutorService 就是個 Thread pool
※最後兩個可排程,但要用 ScheduledExecutorService 去接
※Executors.newFixedThreadPool(1) 等於 Executors.newSingleThreadExecutor(),看原始碼就知道,排程的也是一樣
delay配合TimeUnit的時間間隔,是設定時間用的
delay:多少時間後開始執行
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
以下兩個不容易分
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
initialDelay:多少時間後開始執行,只有第一次
period、delay:第二次(含)之後看的是這個時間
period、delay不同的是
period:command 的開始時間開始算,算到 period 設定的時間為一個間隔,如果設定5秒就每5秒執行一次
delay:command 的結束時間開始算,算到 delay 設定的時間為一個間隔,如果設定5秒就每5秒加上 command 執行的時間執行一次
※注意 future2 的順序,以上面的例子是先執行3秒後的xxx,然後再執行哇哈哈
如果將 future2 放到 future1 的下面,然後在 future1.get() 下增加 future2.get(),最下面的 future2.get() 刪除,此時結果會是1秒的哇哈哈先執行
回傳是否成功取消,如果為false,通常已經正常完成
※註解打開會出「java.util.concurrent.CancellationException」的錯
※取得ExecutorService
以下是overloading,以下只列出同名的其中一個方法ExecutorService s1 = Executors.newCachedThreadPool();// 可快取的 Thread,預設idle 60 秒 ExecutorService s2 = Executors.newFixedThreadPool(3);// 固定數量的 Thread ExecutorService s3 = Executors.newSingleThreadExecutor();// 單一的 Thread ScheduledExecutorService sch1 = Executors.newScheduledThreadPool(3);// 可排程的 Thread ScheduledExecutorService sch2 = Executors.newSingleThreadScheduledExecutor();// 單一可排程的
※最後兩個可排程,但要用 ScheduledExecutorService 去接
※Executors.newFixedThreadPool(1) 等於 Executors.newSingleThreadExecutor(),看原始碼就知道,排程的也是一樣
※ScheduledExecutorService
ScheduledExecutorService 有4個方法delay配合TimeUnit的時間間隔,是設定時間用的
delay:多少時間後開始執行
<V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit)
ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit)
以下兩個不容易分
ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)
ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)
initialDelay:多少時間後開始執行,只有第一次
period、delay:第二次(含)之後看的是這個時間
period、delay不同的是
period:command 的開始時間開始算,算到 period 設定的時間為一個間隔,如果設定5秒就每5秒執行一次
delay:command 的結束時間開始算,算到 delay 設定的時間為一個間隔,如果設定5秒就每5秒加上 command 執行的時間執行一次
※排程範例
ScheduledExecutorService sch1 = Executors.newScheduledThreadPool(1);
ScheduledExecutorService sch2 = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<String> future1 = sch1.schedule(new Callable<String>() {
public String call() throws Exception {
return "xxx";
}
}, 3, TimeUnit.SECONDS);
try {
System.out.println(future1.get());
sch1.shutdown();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
ScheduledFuture<?> future2 = sch2.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("哇哈哈");
}
}, 1, 1, TimeUnit.SECONDS);
try {
future2.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
※注意 future2 的順序,以上面的例子是先執行3秒後的xxx,然後再執行哇哈哈
如果將 future2 放到 future1 的下面,然後在 future1.get() 下增加 future2.get(),最下面的 future2.get() 刪除,此時結果會是1秒的哇哈哈先執行
※Future 的 cancel 方法
參數是布林值,表示如果任務正在執行,是否要取消回傳是否成功取消,如果為false,通常已經正常完成
ScheduledExecutorService sch = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> future = sch.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println("哇哈哈");
}
}, 1, 1, TimeUnit.SECONDS);
ScheduledFuture<?> f = sch.schedule(new Callable<Boolean>() {
public Boolean call() throws Exception {
return future.cancel(true);
}
}, 5, TimeUnit.SECONDS);
try {
// System.out.println(future.get());
System.out.println("是否取消=" + f.get());
sch.shutdown();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
※註解打開會出「java.util.concurrent.CancellationException」的錯
2017年3月6日 星期一
集合、ThreadLocal (Thread 五)
※集合
System.out.println("synchronized list");
List<Integer> l = new ArrayList<>();
synchronized (l) {
l.add(1);
l.add(2);
l.add(3);
}
for (Integer i : l) {
System.out.println(i);
}
System.out.println();
System.out.println("synchronizedCollection");
Collection<String> c = Collections.synchronizedCollection(new ArrayList<>());
c.add("A");
c.add("B");
c.add("C");
synchronized (c) {
for (String s : c) {
System.out.println(s);
}
}
System.out.println();
System.out.println("synchronizedList");
List<String> list = Collections.synchronizedList(new ArrayList<>());
list.add("D");
list.add("E");
list.add("F");
synchronized (list) {
for (String s : list) {
System.out.println(s);
}
}
System.out.println();
System.out.println("synchronizedSet");
Set<String> set = Collections.synchronizedSet(new HashSet<>());
set.add("G");
set.add("H");
set.add("G");
synchronized (set) {
for (String s : set) {
System.out.println(s);
}
}
System.out.println();
System.out.println("synchronizedMap");
Map<Integer, String> map = Collections.synchronizedMap(new HashMap<>());
map.put(0, "A");
map.put(1, "B");
map.put(2, "C");
for (int i = 0; i < map.size(); i++) {
System.out.println(map.get(i));
}
※這些是 java 1.5 之前的寫法,for 迴圈有用 synchronized ,是因為使用到 Iterator ,它並不是 Thread-safe,而 for each 會用到 Iterator 物件,但最原始的 for 迴圈不會用到
※ java 1.5 集合
System.out.println("CopyOnWriteArrayList");
List<String> list = new CopyOnWriteArrayList<>();
list.add("D");
list.add("E");
list.add("F");
for (String s : list) {
System.out.println(s);
}
System.out.println();
System.out.println("CopyOnWriteArraySet");
Set<String> set = new CopyOnWriteArraySet<>();
set.add("G");
set.add("H");
set.add("G");
for (String s : set) {
System.out.println(s);
}
System.out.println();
System.out.println("ConcurrentHashMap");
Map<Integer, String> map = new ConcurrentHashMap<>();
map.put(0, "A");
map.put(1, "B");
map.put(2, "C");
for (int i = 0; i < map.size(); i++) {
System.out.println(map.get(i));
}
※java 1.5 新增了 java.util.concurrent 這個套件
※ThreadLocal
ThreadLocal 是 Thread 變數,在寫 Thread-safe 是很困難的,要讓 Thread 共用,又要同步,又有效能的問題,還要小心 Dead Lock,所以有人想到不要共用了,直接創造 Thread 的複本,在 java 1.2 就產生了 ThreadLocal 類別了,但此方法會需要較多的記憶體※
public class ThreadTest extends Thread {
private static int number;
public int getNumber() {
number = number + 1;
return number;
}
// private static ThreadLocal<Integer> number = new ThreadLocal<Integer>() {
// @Override
// protected Integer initialValue() {
// return 0;
// }
// };
// public int getNumber() {
// number.set(number.get() + 1);
// return number.get();
// }
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + "=" + getNumber());
}
}
public static void main(String... a) {
ThreadTest t1 = new ThreadTest();
ThreadTest t2 = new ThreadTest();
ThreadTest t3 = new ThreadTest();
t1.start();
t2.start();
t3.start();
}
}
※結果:
Thread-0=1
Thread-0=4
Thread-0=5
Thread-1=3
Thread-1=6
Thread-1=7
Thread-2=2
Thread-2=8
Thread-2=9
可以看得出來 Thread 之間被影響了,應該三個 Thread 都是 123 才是正確的
※打開註解並註解原來的 number 和 getNumber(),結果如下:
Thread-0=1
Thread-0=2
Thread-0=3
Thread-2=1
Thread-2=2
Thread-2=3
Thread-1=1
Thread-1=2
Thread-1=3
synchronized、volatile、wait、notify、notifyAll (Thread 四)
synchronized 是同步的意思,其中一個 Thread 執行後,其他的 Thread 也要知道,所以在聲明的區塊裡,一次只能有一個 Thread 執行 (static 除外) ,可以寫在方法、區塊、static method 裡,有四種方式
使用 volatile 宣告的變數,會在記憶體裡取値;沒宣告會在 cache 取值,所以宣告 volatile 後會比較慢
但沒宣告 volatile 有可能記憶體裡的值已被更改,造成資料不同步,所以非必要不要加
在兩個以上 (含) 的 Thread 會使用到的成員變數可以加 volatile,但如果成員變數已在 synchronized 裡或有 final 關鍵字,就不必加了
※for 迴圈模擬提款的時間
※synchronized 寫在方法和 synchronized() 差在,一個是整個方法都 synchronized;另一個是synchronized 區塊裡才是 synchronized,所以外面可以加一些和 synchronized 無關的程式碼,效能會比較好
※另外兩個synchronized 是 static 的,其中一個和寫在方法一樣,另一個是synchronized(Xxx.class)
※
這三個方法都是 Object 的,都必需寫在 synchronized 裡,否則會出「java.lang.IllegalMonitorStateException」的錯
使用 wait 後,必需用 notify 或 notifyAll 喚醒,兩者差在一個呼叫一個 Thread;另一個呼叫全部的 Thread,呼叫哪一個或呼叫的 Thread 順序,是以 JVM 的算法為準,不是優先權值
wait 會釋放鎖,所以一執行完這一行,其他的 Thread 可以呼叫
※結果:
call wail:Thread[main,5,main]
call notify:Thread[Thread-0,5,main]
...
......
※Thread.currentThread 印出的是「Thread 名稱、優先權值、Thread 群組名稱」
※
※
volatile
synchronized 只能寫在方法,而 volatile 只能寫在變數使用 volatile 宣告的變數,會在記憶體裡取値;沒宣告會在 cache 取值,所以宣告 volatile 後會比較慢
但沒宣告 volatile 有可能記憶體裡的值已被更改,造成資料不同步,所以非必要不要加
在兩個以上 (含) 的 Thread 會使用到的成員變數可以加 volatile,但如果成員變數已在 synchronized 裡或有 final 關鍵字,就不必加了
※synchronized
class ATM implements Runnable {
private Account a;
private Integer money;
public ATM(Account a, Integer money) {
this.a = a;
this.money = money;
}
@Override
public void run() {
a.executeWithDraw(a, money);
}
}
class Account {
private int totalMoney;
public Account(int money) {
this.totalMoney = money;
}
public int getTotalMoney() {
return totalMoney;
}
public void executeWithDraw(Account a, int money) {
synchronized (this) {
System.out.print("帳號:" + Thread.currentThread().getName());
int tmpTotalMoney = totalMoney;
for (int i = 1; i <= 99999; i++);
tmpTotalMoney -= money;
if (tmpTotalMoney < 0) {
System.out.println("$不夠");
} else {
totalMoney = tmpTotalMoney;
}
System.out.println("領" + money + "元, 剩" + a.getTotalMoney() + "元");
}
}
}
※for 迴圈模擬提款的時間
※synchronized 寫在方法和 synchronized() 差在,一個是整個方法都 synchronized;另一個是synchronized 區塊裡才是 synchronized,所以外面可以加一些和 synchronized 無關的程式碼,效能會比較好
※另外兩個synchronized 是 static 的,其中一個和寫在方法一樣,另一個是synchronized(Xxx.class)
※測試
Account a = new Account(10000);
System.out.println("目前共" + a.getTotalMoney() + "元");
Thread t1 = new Thread(new ATM(a, 5000));
Thread t2 = new Thread(new ATM(a, 2000));
Thread t3 = new Thread(new ATM(a, 4000));
t1.start();
t2.start();
t3.start();
※
※wait、notify、notifyAll
這三個方法都是 Object 的,都必需寫在 synchronized 裡,否則會出「java.lang.IllegalMonitorStateException」的錯
使用 wait 後,必需用 notify 或 notifyAll 喚醒,兩者差在一個呼叫一個 Thread;另一個呼叫全部的 Thread,呼叫哪一個或呼叫的 Thread 順序,是以 JVM 的算法為準,不是優先權值
wait 會釋放鎖,所以一執行完這一行,其他的 Thread 可以呼叫
public class ThreadTest extends Thread {
@Override
public void run() {
synchronized (this) {
System.out.println("call notify:" + Thread.currentThread());
notify();
}
}
public static void main(String... a) {
ThreadTest t = new ThreadTest();
t.start();
synchronized (t) {
System.out.println("call wail:" + Thread.currentThread());
try {
t.wait();
System.out.println("...");
} catch (InterruptedException e) {
System.out.println("wait interrupted!");
}
System.out.println("......");
}
}
}
※結果:
call wail:Thread[main,5,main]
call notify:Thread[Thread-0,5,main]
...
......
※Thread.currentThread 印出的是「Thread 名稱、優先權值、Thread 群組名稱」
※以喝完水要加水為例
class Water {
private static boolean empty = true;
public synchronized void put(int i) {
if (!empty) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("加第" + i + "次水");
empty = false;
notify();
}
public synchronized void eat(int i) {
if (empty) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("喝第" + i + "次水");
empty = true;
notify();
}
}
class Drink implements Runnable {
Water w;
Drink(Water c) {
this.w = c;
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
w.eat(i);
}
}
}
class Add implements Runnable {
Water w;
Add(Water c) {
this.w = c;
}
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
w.put(i);
}
}
}
※
※測試
Water c = new Water(); Thread p = new Thread(new Add(c)); Thread e = new Thread(new Drink(c)); e.start(); p.start();
※
2017年3月2日 星期四
優先權、join、yield、sleep、interrupt (Thread 三)
※優先權
public class ThreadTest extends Thread {
@Override
public void run() {
System.out.println("name=" + Thread.currentThread().getName());
System.out.println("priority=" + Thread.currentThread().getPriority());
}
public static void main(String... a) {
Thread t = new Thread(new ThreadTest());
t.start();
t.setPriority(MAX_PRIORITY);
}
}
※預設優先權為5,可設1~10的正整數,數字越大,優先權越高
※Thread 類別有三個field,MIN_PRIORITY、NORM__PRIORITY、MAX__PRIORITY,數字分別是 1、5、10,想設其他的就要自己寫死的了,但如果不在 1~10 裡,會出「java.lang.IllegalArgumentException」的錯
※join
哪一個 Thread 使用 join ,那就會先執行完自己的Thread,結束後才會執行其他的 Threadpublic class ThreadTest extends Thread {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println("join=" + i);
}
}
public static void main(String... a) {
Thread t = new Thread(new ThreadTest());
t.start();
for (int i = 1; i <= 50; i++) {
if (i == 10) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main=" + i);
}
}
}
※i==10 後,會先將 join 的部分完成,最後才執行 main 的 Thread
※結果:
main=1
main=2
main=3
...
main=9
join=1
join=2
join=3
...
join=50
main=10
main=11
main=12
...
main=50
※yield
屈服的意思,是靜態方法,在哪個 Thread 寫 yield 就是哪個 Thread使 Thread 讓出執行權,每個 Thread 會被分配到一小段 CPU 時間,時間結束就會換下一個 Thread,就算沒執行完也會換,如果執行這個方法,表示讓出執行權,讓其他 Thread 有機會執行,但也不是強制的
public class ThreadTest extends Thread {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
if (i % 10 == 0) {
Thread.yield();
}
System.out.println("yield=" + i);
}
}
public static void main(String... a) {
Thread t = new Thread(new ThreadTest());
t.start();
for (int i = 1; i <= 50; i++) {
System.out.println("main=" + i);
}
}
}
※結果:
main=1
main=2
main=3
...
main=8
yield=1
yield=2
yield=3
...
yield=19
main=9
main=10
main=11
...
main=50
yield=20
yield=21
yield=22
...
yield=50
※以這個例子為例,一開始兩個 Thread 會互相取得執行權,10、20、30、40,yield 會讓 main 先執行,但因為不是強制的,所以10 並沒有換 main 執行,但到了20 就換 main 了,但 main 一口氣就執行完了,所以最後的30、40 也不用管 main 了
※sleep
sleep 和 yield 一樣,都是讓給其他 Thread 執行,也都是靜態方法public class ThreadTest extends Thread {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
if (i % 10 == 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("sleep=" + i);
}
}
public static void main(String... a) {
Thread t = new Thread(new ThreadTest());
t.start();
for (int i = 1; i <= 50; i++) {
System.out.println("main=" + i);
}
}
}
※結果:
main=1
main=2
main=3
sleep=1
main=4
main=5
main=6
...
main=18
sleep=2
sleep=3
sleep=4
...
sleep=9
main=19
main=20
main=21
...
main=45
sleep=10
main=46
main=47
main=48
main=49
main=50
sleep=11
sleep=12
sleep=13
...
sleep=50
※interrupt
public class ThreadTest extends Thread {
@Override
public void run() {
try {
System.out.println("1");
Thread.sleep(5000);
System.out.println("2");
} catch (InterruptedException e) {
System.out.println("3");
// return;
}
System.out.println("4");
}
public static void main(String... a) {
Thread t = new Thread(new ThreadTest());
t.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("5");
t.interrupt();
System.out.println("6");
}
}
※結果:
1
5
3
4
6
※interrupt 後會被catch 攔截,但要注意如果沒有 return 或 break,還是會繼續執行
※yield 和 sleep 的差別
1.yield 不用參數,sleep 必需給參數2.yield 只能讓同優先級的執行,但只是建議;sleep 不管優先級,只要是 Thread 就可執行
以上兩種方法不會釋放鎖
還有一個 Object 裡的 wait(),很像sleep,但會釋放鎖
訂閱:
文章 (Atom)