java se 四大块 之线程(下)

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{
@Override
public 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();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值