1.Thread类
-java.lang.Thread -线程继承Thread类,实现run方法
public class Thread1 extends Thread{
public void run(){}
}
2.Runnable接口
-java.lang。Runnable接口
-线程实现Runnable接口,实现run方法
实现Runnable的对象必须包装在Thread类里面,才可以启动
public class Thread2 implements Runnable{
public void run(){}
}
拓展:java的四个主要接口
(1)Clonable ,用于对象克隆;
(2)Comparable,用于对象比较;
(3)Serializable,用于对象序列化;
(4)Runnalbe,用于对象线程化;
线程启动
- start方法,会自动以新进程调用run方法
- 直接调用run方法,将会变成串行执行(即一个CPU去执行一个进程))
- 同一个进程,多次start会报错,只执行第一次start方法(多线程对象都start后,哪一个先执行,完全由JVM操作系统来主导,程序员无法指定)
- 多个线程启动,其启动的先后顺序是随机的
- 线程无需关闭,只要其run方法执行结束后,自动关闭
- main函数(线程)可能早于线程结束,整个程序并不终止
- 整个程序终止是等所有的线程都终止(包括main函数线程)
Thread VS Runnable
–Thread类实现Runnable
–Thread占据了父类的名额(不能再去继承其它的类了),不如Runnable方便
–Runnable启动时需要Thread类的支持
–Runnable更容易实现多线程中的资源共享
–结论:建议实现Runnable接口来完成多线程
二、JAVA多线程信息共享
- 通过static变量(一般是通过继承Thread类来实现)
- 同一个Runnable类的成员变量(不需要设置静态变量static)
- (volatile关键字):解决主存与工作缓存数值不相等的问题
关键步骤加锁限制
-
互斥:某一个线程运行一个代码段(关键区),其它线程不能同时运行这个代码段。
-
同步:多个线程的运行,必须按照某一种规定的先后顺序来运行。
-
互斥是同步的一个特例;
互斥的关键字synchronized -synchronized代码块/函数,只能一个线程进入;
synchronized加大性能负担,但是使用简便 ;
抢到锁的线程运行代码块,没有抢到锁的线程则去等待;
JAVA多线程管理
1.线程状态
- -NEW刚创建(new)
- -RUNNABLE就绪态(start)
- -RUNNING运行态(run)
- -BLOCK阻塞(sleep)
- -TERMINATED结束
2.线程的消亡
-
Thread的部分API已经废弃
-
暂停和恢复suspend/resume
-
消亡stop/destroy
-
线程阻塞和唤醒
a. sleep,时间一到,自己会醒来 b. wait/notify/notifyAll,等待,需要别人来唤醒 c. join,等待另一个线程结束 d. -interrupt,向另一个线程发送中断信号,该线程收到信号会触InterruptedException(可 解除阻塞),并进行下一步处理。
3.线程的暂停和终止
-
•线程被动的暂停和终止
○ 依靠别的线程来拯救自己 ○ 没有及时释放资源
-
•线程主动暂停和终止
○ 定期检测共享变量 ○ 如果需要暂停或者终止,先释放资源,再主动动作 ○ 暂停:Thread.sleep(),休眠 ○ 终止:run方法结束,线程终止
4.死锁
-
•多线程死锁
○ 每个线程互相持有别人需要的锁(哲学家吃面问题) ○ 预防死锁,对资源进行等级排序
-
守护(后台)线程
○ 普通线程的结束,是run方法结束 ○ 守护线程结束,是run方法运行结束,或main函数结束 ○ 守护线程永久不要访问资源,如文件或数据库等
t.setDaemon(ture)//t是一个线程
三、java线程案例(生产者和消费者案例、死锁案例): 案例一:生产者与消费者
Test.java代码如下
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Storage storage=new Storage();
//创建两个生产者
Producer p1=new Producer(storage);
Producer p2=new Producer(storage);
//创建消费者两个
Consumer c1=new Consumer(storage);
Consumer c2=new Consumer(storage);
Thread t3=new Thread(p1);
Thread t4=new Thread(p2);
t3.setName("生产者t3");
t4.setName("生产者t4");
Thread t1=new Thread(c1);
Thread t2=new Thread(c2);
t1.setName("消费者t1");
t1.setName("消费者t2");
t3.start();
t4.start();
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t1.start();
t2.start();
}
}
Storage.java代码如下:(仓库)
public class Storage {
private Product[] products=new Product[10];
private int top=0;
//生产一个产品
public synchronized void push(Product p) throws InterruptedException {
//当仓库满的时候
while(top==products.length) {
System.out.println("仓库已满 wait");
wait();
}
//仓库不满的时候
products[top]=p;
top++;
System.out.println(Thread.currentThread().getName()+"生产一个商品"+p);
notifyAll();
}
//消耗一个产品
public synchronized Product pop() throws InterruptedException {
//当仓库没有商品时
while(top==0) {
System.out.println("仓库为空 wait");
wait();
}
//当仓库有商品时
top--;
Product p=new Product(products[top].getId(),products[top].getName());
products[top]=null;
System.out.println(Thread.currentThread().getName()+"消费一个商品"+p);
notifyAll();
return p;
}
}
Product.java代码如下:(产品)
public class Product {
private int id;
private String name;
Product(int id ,String name){
this.id=id;
this.name=name;
}
public String toString() {
return "id:"+id+"name:"+name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
Consumer.java代码如下:(消费者)
public class Consumer implements Runnable {
private Storage storage;
public Consumer(Storage storage) {
// TODO Auto-generated constructor stub
this.storage=storage;
}
public void run() {
int i=0;
while(i<10) {
i++;
try {
storage.pop();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
}
}
Producer.java代码如下:(生产者)
public class Producer implements Runnable {
private Storage storage;
public Producer(Storage storage) {
// TODO Auto-generated constructor stub
this.storage=storage;
}
public void run() {
int i=0;
Random m=new Random();
while(i<10) {
i++;
Product p=new Product(i,"name"+m.nextInt(100));
try {
storage.push(p);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
运行截图:
public class ThredDemo5 {
public static Integer r1=1;
public static Integer r2=2;
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
Thread1 t1=new Thread1();
Thread2 t2=new Thread2();
t1.start();
t2.start();
}
}
class Thread1 extends Thread{
public void run() {
synchronized (ThredDemo5.r2) {
System.out.println("Thread1--llp1 is running !");
}
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (ThredDemo5.r1) {
System.out.println("Thread2--llp2 is running !");
}
}
}
class Thread2 extends Thread{
public void run() {
synchronized (ThredDemo5.r1) {
System.out.println("Thread2--llp1 is running !");
}
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (ThredDemo5.r2) {
System.out.println("Thread2--llp2 is running !");
}
}
}



