前几天去面试,让我用手写个线程的演示程序,憋了半天才憋出来,好在笔试过了,面试就....
这里把线程相关的知识点用代码的形式总结之:
一、死锁:
package cn.bl.thread;
publicclass DeadLock implements Runnable{
//static关键字很重要,它让下面的两个if中的代码操作同样的Object对象
//因为static修饰属性时,该属性被多个当前类(t1、t2)共享,一个类改变了值会影响其他类
static Object o1=new Object();
static Object o2=new Object();
booleanflag;
@Override
publicvoid run() {
// TODO Auto-generated method stub
if(flag){
System.out.println("线程1开始了");
//每个对象身上都有一个锁旗标,用来告诉线程,自己同步的代码是否可以访问
synchronized(o1){
System.out.println("线程1锁住o1,再锁住o2就顺利结束");
//Thread.yield();
try {
Thread.sleep(700);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(o2){
System.out.println("锁住o2");
}
}
System.out.println("线程1顺利结束");
}
if(!flag){
System.out.println("线程2开始了");
synchronized(o2){
System.out.println("线程2锁住o2,再锁住o1就顺利结束");
//Thread.yield();暂停当前正在执行的线程对象,并执行其他线程。
try {
Thread.sleep(700);//在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)仍然抱着锁
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized(o1){
System.out.println("锁住o1");
}
}
System.out.println("线程2顺利结束");
}
}
publicstaticvoid main(String[] args) {
DeadLock t1=new DeadLock();
t1.flag=true;
DeadLock t2=new DeadLock();
t2.flag=false;
Thread thread1=new Thread(t1);
Thread thread2=new Thread(t2);
thread1.start();
thread2.start();
}
}
二、生产者--消费者
模拟过程:3个Producer线程生成馒头(ManTou)并放入栈(SyncStack)中,Cousumer类负责消费。
package cn.bl.thread;
//这是馒头类
publicclass ManTou {
}
package cn.bl.thread;
import java.util.Vector;
//模拟放馒头的栈
publicclass SyncStack {
publicstatic String lock="";
//存放馒头用
//Vector 类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是,Vector 的大小可以根据需要增大或缩小,以适应创建 Vector 后进行添加或移除项的操作。
Vector stack;
SyncStack(){
stack=new Vector();
}
/**
* 放入馒头
*/
publicvoid inManTou(ManTou mt){
synchronized(lock){
if(stack.size()==15){
System.out.println("栈已满,请等待");
try {
//Object.wait 在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
stack.add(mt);
System.out.println(Thread.currentThread().getName()+"生产了一只馒头并放入了栈中, 现在栈中有: "+stack.size()+"个馒头");
lock.notify();//唤醒在此对象监视器上等待的单个线程。
}
}
}
/**
* 拿出馒头
*/
publicvoid outMantou(){
synchronized (lock) {
if(stack.size()==0){
System.out.println("栈中没有馒头,请等待");
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
stack.remove(0);
System.out.println(Thread.currentThread().getName()+"吃了一个馒头,栈中此时剩余馒头: "+stack.size());
lock.notify();
}
}
}
}
package cn.bl.thread;
//模拟生产者
publicclass Producter implements Runnable{
SyncStack ss;
ManTou mt;
Producter(SyncStack ss){
this.ss=ss;
}
//生产馒头,因为栈的inManTou方法已经做了同步处理,这里就不需要synchronized了
publicvoid product(){
{
mt=new ManTou();
ss.inManTou(mt);
}
}
//不断的生产
@Override
publicvoid run() {
// TODO Auto-generated method stub
while(true){
synchronized (this) {
try {
Thread.sleep(400);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.product();
}
}
}
package cn.bl.thread;
publicclass Customer implements Runnable{
SyncStack ss;
Customer(SyncStack ss){
this.ss=ss;
}
publicvoid eat(){
ss.outMantou();
}
@Override
publicvoid run() {
// TODO Auto-generated method stub
while(true){
synchronized (this) {
try {
Thread.sleep(800);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.eat();
}
}
}
}
package cn.bl.thread;
publicclass Test {
publicstaticvoid main(String[] args) {
SyncStack ss=new SyncStack();
Producter p1=new Producter(ss);
Producter p2=new Producter(ss);
Producter p3=new Producter(ss);
Producter p4=new Producter(ss);
Customer c1=new Customer(ss);
Customer c2=new Customer(ss);
Thread tp1=new Thread(p1);
Thread tp2=new Thread(p2);
Thread tp3=new Thread(p3);
Thread tp4=new Thread(p4);
tp1.setName("钢铁侠");
tp2.setName("绿巨人");
tp3.setName("蝙蝠侠");
tp4.setName("蜘蛛侠");
Thread tc1=new Thread(c1);
Thread tc2=new Thread(c2);
tc1.setName("吃货1");
tc2.setName("吃货2");
tp1.start();
tp2.start();
tp3.start();
tp4.start();
tc1.start();
tc2.start();
}
}