java se 四大块 之线程(下)

来源:互联网 发布:office2016 mac 10.9 编辑:程序博客网 时间:2024/06/06 17:21
public class Test{public   static void main(String []args)   throws  InterrruptedException{Thread1  t=new Thread1();Thread  th1=new  Thread(t);Thread  th2=new  Thread(t);Thread  th3=new  Thread(t);Thread  th4=new  Thread(t);th1.start();th2.start();th3.start();th4.start();th1.join();th2.join();th3.join();th4.join();System.out.println("程序结束");}}class Thread1  implements  Runnable{private  int num=200;public  void run (){while (num>0){System.out.println(Thread.currentThread().getName+"窗口买卖了第"+num+“张票”);num--;}}}//上面的程序运行完会有重复的购票可能,可加一个同步代码块或者是同步方法来解决,也就是synchronized关键字 修饰代码块或者方法。
public  class Test{public static void main(String  []args{Bank bank=new Bank(fectmoney);Thread t=new Thread(bank);t.start();}}class FectMoney  {private int money=1000;public synchronized  int getMoney(int number){if(money>number){return -1;}else if(money>0){return -2;}  else if(number>0){return  -3;}else{try{Thread.sleep(1000);}catch(InterruptedException  e){e.printStackTrace();mongey -=number;System.out.println(number);return money;}}}}class Bank   implements  Runnable {private FectMoney fectmoney;public Bank(FectMoney fectmoney){this.fectmoney=fectmoney;public void run (){fectmoney.getMoney();}}public class Test {    public static void main(String[] args) {        FectMoney fectMoney = new FectMoney();        Bank bank = new Bank(fectMoney);        Thread t = new Thread(bank);        Thread t2 = new Thread(bank);        t.start();        t2.start();    }}class FectMoney {    private int money = 1000;    public synchronized int getMoney(int number) {        if (money <number) {            return -1;        } else if (money < 0) {            return -2;        } else if (number < 0) {            return -3;        } else {            try {                Thread.sleep(1000);                money -= number;                System.out.println(number);            } catch (InterruptedException e) {                e.printStackTrace();                money -= number;                System.out.println(number);            }        }        return money;    }}class Bank implements Runnable {    private FectMoney fectmoney;    public Bank(FectMoney fectmoney) {        this.fectmoney = fectmoney;    }    @Override    public void run() {        System.out.println(fectmoney.getMoney(800));    }}}//一般我们不在run方法上加锁,而是在我们 需要中 的实际功能块上加锁,此例子是证明两个人同时从一个银行账取钱的例子

同步的时候的可能会造成,原因是因为锁 的同步嵌套。两个同步用的不是一把锁,也就是锁的嵌套顺序不一样,死锁的时候,资源不能被共享,请求与保持条件,已经得到线程资源还可以在申请新的资源,已经分配的锁,不能在相应的线程中强行剥夺,在系统中若干线程形成环路,在环路中每个线程都等待相邻线程释放资源。所以尽量不要使用锁的嵌套。容易造成死锁现象。

我说一下单例模式的线程安全时的代码:

public  Test{public static void main(){ThreadTest t  =new ThreadTest();Thread   th1=new Thread(t);Thread  th2=new Thread (t);th1.start();th2.start();}  }class Single{private staic Single single;private Single(){}public static   synchronized  Single getNewInstance(){if(single==null){return single =new Single();}return single;}}class ThreadTest extends  RUnnable{@Overridepublic void  run(){System.out.println(Single.getNewInstacne());}}//执行结果里面的地址值是一样的。说明也就是线程安全的单例模式,在没有加锁的时候,当我们使用多线程访问单例模式的时候,一个线程在判断single是否为空时,是null,系统又切换到另一个线程,此时在进行判断single是否为空,也是 为空,然后new一个Single();而另外一个线程在执行时,他已经判断完了,就会在new一个Single();这也就不是但单例模式了,其实线程安全的单例模式的也不是 绝对的安全的,我们任然可以通反射机制来访问单例模式的私有构造器,来破坏单例模式。
public class MainTest{    public static void main(String[] args)    {        Sample sample = new Sample();        Thread t1 = new IncreaseThread(sample);        Thread t2 = new DecreaseThread(sample);        Thread t3 = new IncreaseThread(sample);        Thread t4 = new DecreaseThread(sample);        t1.start();        t2.start();        t3.start();        t4.start();    }} class DecreaseThread extends Thread{private Sample sample;    public DecreaseThread(Sample sample)    {        this.sample = sample;    }    @Override    public void run()    {        for(int i = 0; i < 20; i++)        {            try            {                Thread.sleep((long)(Math.random() * 1000));            }            catch (InterruptedException e)            {                e.printStackTrace();            }            sample.decrease();        }    }}class IncreaseThread extends Thread{    private Sample sample;    public IncreaseThread(Sample sample)    {        this.sample = sample;    }    @Override    public void run()    {        for(int i = 0; i < 20; i++)        {            try            {                Thread.sleep((long)(Math.random() * 1000));            }            catch (InterruptedException e)            {                e.printStackTrace();            }            sample.increase();        }    }}class Sample{    private int number;    public synchronized void increase()    {        while (0 != number)        {            try            {                wait();            }            catch (InterruptedException e)            {                e.printStackTrace();            }        }        number++;        System.out.println(number);        notify();    }    public synchronized void decrease()    {        while (0 == number)        {            try            {                wait();            }            catch (InterruptedException e)            {                e.printStackTrace();            }        }        number--;        System.out.println(number);        notify();    }}//两个线程类  四个线程对象,连个实现增加操作,两个实现减操作,使得数字始终是  1,0 1 0。。。。其中增加了wait方法和notify方法用已在线程之间进行通信。这两个房方法应该放在锁中,当执行到wait方法时,该线程就会释放掉锁,处于等待状态当另一个线程执行到,notify方法时,也会释放锁,并通知处于等待状态的线程继续往下执行。

lock

import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class MainTest{    public static void main(String[] args)    {        Sample sample = new Sample();        Thread t1 = new IncreaseThread(sample);        Thread t2 = new DecreaseThread(sample);        Thread t3 = new IncreaseThread(sample);        Thread t4 = new DecreaseThread(sample);        t1.start();        t2.start();        t3.start();        t4.start();    }} class DecreaseThread extends Thread{private Sample sample;    public DecreaseThread(Sample sample)    {        this.sample = sample;    }    @Override    public void run()    {        for(int i = 0; i < 20; i++)        {            try            {                Thread.sleep((long)(Math.random() * 1000));            }            catch (InterruptedException e)            {                e.printStackTrace();            }            sample.decrease();        }    }}class IncreaseThread extends Thread{    private Sample sample;    public IncreaseThread(Sample sample)    {        this.sample = sample;    }    @Override    public void run()    {        for(int i = 0; i < 20; i++)        {            try            {                Thread.sleep((long)(Math.random() * 1000));            }            catch (InterruptedException e)            {                e.printStackTrace();            }            sample.increase();        }    }}  class Sample {    private int number;    Lock lock = new ReentrantLock();    Condition condition = lock.newCondition();    public void increase() {        lock.lock();        try {            while (0 != number) {                try {                    condition.await();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            number++;            System.out.println(number);            condition.signalAll();        } catch (Exception e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }    public void decrease()    {        lock.lock();        try {            while (0 == number) {                try {                    condition.await();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            number--;            System.out.println(number);            condition.signalAll();        } catch (Exception e) {            e.printStackTrace();        } finally {            lock.unlock();        }    }}
原创粉丝点击