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