線程的基礎內容
程序、進程、線程
- 一個進程中至少有一個線程
各個應用程序之間去搶佔CPU資源,在同一個時間點上,CPU只能處理一個程序,看上去像是同時在進行,其實是CPU在快速的切換,進程搶佔到CPU資源後,各個線程就去搶,那個線程先搶到就執行那個線程,(所以每一次執行的順序都不一樣) - 在java虛擬機上啓動的時候會有一個進程java.exe,該進程中至少有一個線程,在負責java程序的執行。而且這個線程運行的代碼在main方法中,該線程爲主線程
- 但是線程結束,進程未必結束,但進程結束,線程一定結束,線程是進程中的一部分
線程的創建和啓動
- 在java中負責線程的這個功能的是java.lang.Thread這個類
- 可以通過new Thread(創建Thread的實例)來創建新的線程
- 每個都是通過某個特定Thread對象所對應的run()方法完成其操作,run()方法稱爲線程體。
- 可以通過調用Thread類的start()方法來啓動一個線程。
- 繼承Thread類 ,重寫run方法,創建對象,調用start()方法,啓動線程。
代碼如下:
public class A extends Thread{
@Override
public void run() {
System.out.println("我是A");
}
public static void main(String[] args) {
A a=new A();
Thread t=new Thread(a);
a.start();
}
}
-
- 創建線程的第二個方式:
- 實現Runnable接口,重寫run方法,創建對象,啓動線程。
代碼如下:
public class B implements Runnable{
@Override
public void run() {
System.out.println("我是B");
}
public static void main(String[] args) {
B b=new B();
Thread t=new Thread(b);
//也可以這樣 Thread t=new Thread(new B());
t.start();
}
}
- 以上都是單線程,下面一個多線程的應用:
賣票
public class ThreadDemo6 implements Runnable{
int Ticket=5;
@Override
public void run() {
for(int i=0;i<100;i++){
if(Ticket>0){
System.out.println(Thread.currentThread().getName()+"正在出售"+(Ticket--)+"車票");
}
}
}
public static void main(String[] args) {
ThreadDemo6 t = new ThreadDemo6();
Thread t1=new Thread(t);
Thread t2=new Thread(t);
Thread t3=new Thread(t);
Thread t4=new Thread(t);
t1.start();
t2.start();
t4.start();
t3.start();
}
}
有可能出現這樣的現象:
5張車票,出售了6張
Thread-0正在出售5車票
Thread-2正在出售2車票
Thread-2正在出售1車票
Thread-3正在出售3車票
Thread-1正在出售4車票
Thread-0正在出售0車票
這樣就用到了線程的同步
線程同步
- 用到了:synchronized,這個可以是同步代碼塊,同步對象。
線程同步的實現
public class ThreadDemo15 implements Runnable{
int sum=5;
@Override
public synchronized void run() {
for (int i = 0; i < 200; i++) {
if(sum>0){
System.out.println(Thread.currentThread().getName()+"出售"+sum--+"票");
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
ThreadDemo15 t = new ThreadDemo15();
Thread t0 = new Thread(t);
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
- 死鎖
- 同步可以保證資源共享操作的正確性,但是過多同步也會產生死鎖, 死鎖一般情況下表示互相等待,是程序運行時出現的一種問題。
- 例如:
想要畫的張山跟想要書李四說:“把你的畫給我,我把我的書給你”,李四也說:“把書給我,我把畫給你”。然後倆個人互相等待
線程間通信
–
線程間通信的實現
public class communication01 {
public static void main(String[] args){
final besiness b=new besiness();
new Thread(new Runnable() {
@Override
public void run() {
for(int i=1;i<=50;i++){
b.sub(i);
}
}
}).start();
for (int i = 1; i <= 50; i++) {
b.main(i);
}
}
}
class besiness{
private static boolean flag=true;//flag爲true時允許main訪問,爲false時允許suB訪問
public synchronized void main(int i){
while(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 10; j++) {
System.out.println("main thread==" + j + ",loop of " + i);
}
flag=false;
this.notify();
}
public synchronized void sub(int i){
while (flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 1; j <= 10; j++) {
System.out.println("sub thread==" + j + ",loop of " + i);
}
flag=true;
this.notify();
}
}