文章目錄
1.並行與併發
並行:兩個事件在同一時刻發生
併發:兩個事件在同一時間段交替進行
2.進程與線程
進程:我們在內存中運行程序,我們稱之爲進程
線程:完成某個模塊,稱之爲線程,例如迅雷下載
線程是屬於某個進程的,每個進程都至少包含一個線程
線程調度:
分時調度:每個線程平均分配cpu的使用權
搶佔式調度:隨機分配
Java中採用搶佔式調度
3Thread類
右鍵運行程序至少調用兩個線程
main方法的線程稱之爲主線程
垃圾回收器線程
成員方法:
getname獲取線程的名字
setname獲取線程的名字
run代表要執行的任務
start啓動該線程
sleep該線程休眠
currentThread獲取當前線程
3.1創建線程
3.1.1繼承
創建子類,繼承Thread
子類中重寫run方法
創建子類對象
調用start方法
package com.itcast.Text04;
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(currentThread().getName()+i);
}
}
}
package com.itcast.Text04;
public class Demo01 {
public static void main(String[] args) {
MyThread m = new MyThread();
// m.run();
m.start();
for (int i = 0; i < 100; i++) {
System.out.println("main"+i);
}
}
}
3.1.2實現方式
定義實現類
重寫run方法
調用
package com.itcast.Text04;
public class MyRunable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("runable"+i);
}
}
}
package com.itcast.Text04;
public class Text03 {
public static void main(String[] args) {
MyRunable m = new MyRunable();
Thread t = new Thread(m);
t.start();
for (int i = 0; i < 100; i++) {
System.out.println("main" +i);
}
}
}
3.1.3匿名內部類形式
package com.itcast.Text04;
public class Text02 {
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(currentThread().getName() + i);
}
}
}.start();
for (int i = 0; i < 100; i++) {
System.out.println("main"+i);
}
}
}
3.1.4兩種方式的比較
實現類方式比較好,線程和任務是分開的,由程序員自己組合
實現避免了Java單繼承的不足
實現是線程解耦合,繼承是耦合的
4.高併發與線程安全
高併發:某個時間點有大量的用戶訪問同一資源
線程安全:出現高併發後不會出現不符合實際的數據
線程安全的問題:
可見性
有序性:
原子性
5.volatile關鍵字
volatile用來修飾成員變量的靜態方法,可以解決多線程的可見性有序性問題
package com.itcast.Text05;
public class MyThread extends Thread {
public volatile static int a = 0;
@Override
public void run() {
System.out.println("線程啓動了");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("將a的值修改");
a = 1;
System.out.println("線程結束");
}
}
package com.itcast.Text05;
public class Text01 {
public static void main(String[] args) {
MyThread m = new MyThread();
m.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
if (MyThread.a == 1) {
System.out.println("a的值爲1");
return;
}
}
}
}
注意:
volatile不能解決原子性問題
只能解決可見性,順序性
6.原子類
原子類:保證了數據操作的原子性,中間不會被其他線程打斷
AtomicInteger:對變量操作的原子類
getAtomicInteger相當於對原子變量的++
incrementAnGet相當於++變量
package com.itcast.Text05;
import java.util.concurrent.atomic.AtomicInteger;
public class MyThread01 extends Thread {
public static AtomicInteger a = new AtomicInteger();
@Override
public void run() {
for (int i = 0; i < 1000; i++) {
a.getAndIncrement();
}
System.out.println("修改完成");
}
}
package com.itcast.Text05;
public class Text02 {
public static void main(String[] args) throws InterruptedException {
MyThread01 mm = new MyThread01();
MyThread01 mm1 = new MyThread01();
mm.start();
mm1.start();
Thread.sleep(2000);
System.out.println(MyThread01.a);
}
}