一、線程創(chuàng)建
- 繼承Thread類,重寫run方法;
- 實(shí)現(xiàn)Runnable接口;
- 實(shí)現(xiàn)Callable接口;
class MyThread extends Thread {
@Override
public void run() {
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
}
}
class CallableImpl implements Callable<String> {
@Override
public String call() throws Exception {
}
}
public class test {
public static void main(String[] args) {
new MyThread().start();
new Thread(new MyRunnable()).start();
new Thread(new FutureTask<String>(new CallableImpl())).start();
}
}
區(qū)別:繼承只有一次機(jī)會,Runnable實(shí)現(xiàn)不占繼承機(jī)會且可以多實(shí)現(xiàn),Callable有返回值。
二、線程生命周期

主要狀態(tài)包括:創(chuàng)建、就緒、運(yùn)行、阻塞、終止。
sleep()與wait():
sleep:當(dāng)前線程睡眠;
wait: 訪問當(dāng)前對象的線程wait,前提是當(dāng)前方法必須加鎖,如果鎖不住方法,那么調(diào)用的對象wait無從談起。
wait的時(shí)候,鎖被釋放了,sleep的時(shí)候,鎖一直被持有。
notify:叫醒當(dāng)前wait在我這個(gè)對象上的線程。join() 在A線程中調(diào)用B線程的join,意思是兩個(gè)線程合并,A線程要等待B線程執(zhí)行完才恢復(fù)執(zhí)行。
yield()讓出cpu,當(dāng)前線程進(jìn)入就緒隊(duì)列等待調(diào)度。
getPriority()/setPriority():獲取與設(shè)置線程優(yōu)先級。
interrupt()中斷, 配合是否被中斷的方法一起使用,可以停止wait()方法和sleep()方法。
stop()非常粗暴,會強(qiáng)行把執(zhí)行到一半的線程終止,不推薦使用,貌似已經(jīng)廢棄。
三、死鎖
死鎖是兩個(gè)及以上的線程互相持有對方需要的鎖,并且都互相等待對方釋放鎖;
package com.zht.thread;
public class DeadLock implements Runnable {
public int flag = 1;
static Object o1 = new Object(), o2 = new Object();
public void run() {
if (flag == 1) {
synchronized (o1) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o2) {
System.out.println("1");
}
}
}
if (flag == 0) {
synchronized (o2) {
try {
Thread.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (o1) {
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
DeadLock td1 = new DeadLock();
DeadLock td2 = new DeadLock();
td1.flag = 1;
td2.flag = 0;
Thread t1 = new Thread(td1);
Thread t2 = new Thread(td2);
t1.start();
t2.start();
}
}
四、生產(chǎn)者消費(fèi)者模型
這里使用wait和nofify來實(shí)現(xiàn)一個(gè)生產(chǎn)者消費(fèi)者模型
package com.zht.thread;
public class ProducerConsumer {
public static void main(String[] args) {
SyncStack ss = new SyncStack();
Producer p = new Producer(ss);
Consumer c = new Consumer(ss);
new Thread(p).start();
new Thread(p).start();
new Thread(p).start();
new Thread(c).start();
}
}
class WoTou {
int id;
WoTou(int id) {
this.id = id;
}
public String toString() {
return "WoTou : " + id;
}
}
class SyncStack {
int index = 0;
WoTou[] arrWT = new WoTou[6];
public synchronized void push(WoTou wt) {
while (index == arrWT.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
arrWT[index] = wt;
index++;
}
public synchronized WoTou pop() {
while (index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
index--;
return arrWT[index];
}
}
class Producer implements Runnable {
SyncStack ss = null;
Producer(SyncStack ss) {
this.ss = ss;
}
public void run() {
for (int i = 0; i < 20; i++) {
WoTou wt = new WoTou(i);
ss.push(wt);
System.out.println("生產(chǎn)了:" + wt);
try {
Thread.sleep((int) (Math.random() * 200));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable {
SyncStack ss = null;
Consumer(SyncStack ss) {
this.ss = ss;
}
public void run() {
for (int i = 0; i < 20; i++) {
WoTou wt = ss.pop();
System.out.println("消費(fèi)了:" + wt);
try {
Thread.sleep((int) (Math.random() * 1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}