一、多线程可以通过继承Thread类或者继承runnable接口实现,继承接口会比较灵活
线程的程序代码写在继承的类的run()方法内,并且必须调用Thread类中额start()方法来启动
二、sleep()方法,睡眠指定的毫秒数,抛出InterruptedException异常,必须写try catch
interrupt()方法可以中断线程
sleep()方法可以用于迫使线程执行到该处后暂停执行,确实让出CPU给别的线程
三、join()方法,使线程合并(变为单线程),yield()方法,使线程让出CPU占用通道一会儿。setPriority()
四、线程同步
1、synchronized 关键字锁定线程。当某个对象用synchronized修饰,表明该对象在任意时刻只能有一个线程访问
2、死锁的例子:
public class TestDeadLock implements Runnable {
public int flag = 1;
static Object o1 = new Object(), o2 = new Object();
public void run() {
System.out.println("flag=" + flag);
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) {
TestDeadLock td1 = new TestDeadLock();
TestDeadLock td2 = new TestDeadLock();
td1.flag = 1;
td2.flag = 0;
Thread t1 = new Thread(td1);
Thread t2 = new Thread(td2);
t1.start();
t2.start();
}
}
3、synchronized可以锁定方法,也可以锁定代码块,一旦有多个线程都要征用对多个锁的独占访问,就可能死锁
4、生产者消费者
wait() 告诉当前线程放弃监视器并进入睡眠状态,直到其他线程进入同一监视器并调用notify()为止
notify():唤醒同一对象监视器中调用wait的第1个线程
notifyAll():唤醒同一对象监视器中调用wait的所有线程,最高优先级的线程首先被唤醒并执行
/**
* 此程序说明了经典的生产者消费者问题
*/
package MLDN;
public class ThreadCommunation {
public static void main(String[] args) {
P q = new P();
new Thread(new Producer(q)).start();
new Thread(new Consumer(q)).start();
}
}
class Producer implements Runnable {
P q = null;
public Producer(P q) {
this.q = q;
}
public void run() {
int i = 0;
while (true) {
if (i == 0) {
q.set("张三", "男");
} else {
q.set("李四", "女");
}
i = (i + 1) % 2;
}
}
}
class Consumer implements Runnable {
P q = null;
public Consumer(P q) {
this.q = q;
}
public void run() {
while (true) {
q.get();
}
}
}
/* 数据存储空间类,实现线程间通信 */
class P {
private String name = "李四";
private String sex = "女";
boolean bFull = false;
public synchronized void set(String name, String sex) {
if (bFull) {
try {
wait();
} catch (Exception e) {
}
}
this.name = name;
try {
Thread.sleep(500);
} catch (Exception e) {
}
this.sex = sex;
bFull = true;
notify();
}
public synchronized void get() {
if (!bFull) {
try {
wait();
} catch (Exception e) {
}
}
System.out.println(name + "---->" + sex);
bFull = false;
notify();
}
}
在数据空间类P中定义了bFull来表示存储状态。当Consumer线程取走数据后,bFull为false,当Producer线程放入数据后,bFull为true。只有bFull为true时,Consumer线程才能取走数据,否则就必须等待Producer放入新的数据后的通知;反之,只有bFull为false时,Producer线程才能放入新的数据,否则就必须等待Consumer线程取走数据后的通知