Java併發程式設計學習(一)——標準Thread
阿新 • • 發佈:2019-02-10
1、雖然System.out.println內部是加了鎖的,但是如果System.out.println(i- -),依然是執行緒不安全的,因為有的JVM,i- -需要三步才能完成。
2、通過interrupt方法停止執行緒
public class IntteruptStop
{
public static void main(String[] args)
{
try
{
MyThread mt = new MyThread();
mt.start();
Thread.sleep(1000 );
mt.interrupt();
}
catch(Exception e)
{
}
}
private static class MyThread extends Thread
{
@Override
public void run()
{
for(int i = 0; i < 500000; i++)
{
System.out.println("i = " + (i + 1));
//這裡也可以用Thread.interrupted();
if(currentThread().isInterrupted())
{
System.out.println("break");
break;
}
}
//注意,如果這裡還有程式碼,依然會繼續執行
}
}
}
3、interrupted方法會清除狀態標誌,而isInterrupted不會
4、interrupted方法和sleep
public class InterruptSleep
{
public static void main(String[] args)
{
try
{
MyThread mt = new MyThread();
mt.start();
Thread.sleep(1000);
mt.interrupt();
}
catch(Exception e)
{
}
}
private static class MyThread extends Thread
{
@Override
public void run()
{
// for(int i = 0; i < 500000; i++)
// {
// System.out.println("i = " + (i + 1));
// }
try
{
System.out.println(System.currentTimeMillis());
Thread.sleep(5000);
}
catch(InterruptedException e)
{
System.out.println(System.currentTimeMillis());
System.out.println("end");
//這裡標誌已經被清除成false
System.out.println(isInterrupted());
}
}
}
}
可以理解為sleep方法會時刻檢查isInterrupt的值,如果為true就會立刻結束並丟擲異常,同時把標誌清為false。
5、不要使用stop方法
public class StopError
{
public static void main(String[] args)
{
try
{
SynchronizedObject obj = new SynchronizedObject();
MyThread mt = new MyThread(obj);
mt.start();
Thread.sleep(500);
mt.stop();
System.out.println(obj.getUsername() + ", " + obj.getPassword());
}
catch(Exception e)
{
}
}
private static class SynchronizedObject
{
String username = "a";
String password = "aa";
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
public String getPassword()
{
return password;
}
public void setPassword(String password)
{
this.password = password;
}
synchronized void printString(String username, String password)
{
try
{
this.username = username;
Thread.sleep(100000);
this.password = password;
}
catch(InterruptedException e)
{
}
catch(ThreadDeath e)
{
System.out.println(e);
}
}
}
private static class MyThread extends Thread
{
SynchronizedObject obj;
public MyThread(SynchronizedObject obj)
{
super();
this.obj = obj;
}
@Override
public void run()
{
obj.printString("b", "bb");
}
}
}
最終輸出:
java.lang.ThreadDeath
b, aa
也就是說加了鎖的printString方法並未執行完成執行緒就被強行終止,導致不可預知的錯誤。
6、不要使用suspend和resume
package com.amuro.studythread.chapter_1_thread;
public class SuspendError
{
public static void main(String[] args)
{
try
{
SynchronizedObject obj = new SynchronizedObject();
Thread t1 = new Thread(new Runnable()
{
@Override
public void run()
{
obj.printString();
}
});
t1.setName("a");
t1.start();
Thread t2 = new Thread(new Runnable()
{
@Override
public void run()
{
obj.printString();
}
});
t2.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
private static class SynchronizedObject
{
@SuppressWarnings("deprecation")
synchronized void printString()
{
System.out.println(Thread.currentThread().getName() + " : begin");
if(Thread.currentThread().getName().equals("a"))
{
System.out.println(Thread.currentThread().getName() + " : suspend");
Thread.currentThread().suspend();
}
System.out.println(Thread.currentThread().getName() + " : end");
}
}
}
最終輸出
a : begin
a : suspend
也就是說如果a執行緒在使用某同步物件為執行完成時就暫停,會導致該物件在其resume之前永遠無法被其他執行緒訪問。
7、yield方法作用是放棄當前CPU使用權,將它讓給其他任務來佔用CPU執行時間。但放棄的時間不確定,可能剛放棄就又拿到了CPU時間片。
8、執行緒優先順序的特性
1)繼承性,A執行緒中啟動B執行緒,A和B具有一樣的優先順序;
2)規則性,CPU會盡量把執行資源讓給優先順序較高的執行緒;
3)隨機性,和2)相關,儘量不代表一定,所以優先順序高的未必會比優先順序低的先執行完
9、守護執行緒
package com.amuro.studythread.chapter_1_thread;
public class Daemon
{
public static void main(String[] args)
{
try
{
MyThread mt = new MyThread();
mt.setDaemon(true);
mt.start();
Thread.sleep(5000);
//當程序中不存在非守護執行緒時,守護執行緒就被自動銷燬
}
catch(Exception e)
{
}
}
private static class MyThread extends Thread
{
int i = 0;
@Override
public void run()
{
while(true)
{
try
{
i++;
System.out.println("i = " + i);
Thread.sleep(1000);
}
catch (Exception e)
{
}
}
}
}
}