线程基础

前几天去面试,让我用手写个线程的演示程序,憋了半天才憋出来,好在笔试过了,面试就....

这里把线程相关的知识点用代码的形式总结之:

一、死锁:

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();

    }

   

}

二、生产者--消费者

模拟过程:3Producer线程生成馒头(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();

       

       

    }

   

}

 

你可能感兴趣的:(java,多线程,线程)