多线程题目java

100个线程同时向一个银行账户中存入1元钱

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * java编程题:100个线程同时向一个银行账户中存入1元钱 
 */
public class Test {

    public static void main(String[] args) {
        Account account = new Account();
        ExecutorService service = Executors.newFixedThreadPool(100);

        for (int i = 1; i <= 100; i++) {
            service.execute(new MoneyThread(account, 1));
        }

        service.shutdown();

        while(!service.isTerminated()){}

        System.out.println("账户金额:"+account.getBalance());
    }

}

/**
 * 银行账户类
 */
class Account {

    private double balance;         //账户余额

    private Lock accountLock = new ReentrantLock();         //锁对象

    /**
     * 存入金额方法
     * 
     * 实现方式1:
     *    synchronized关键字修饰方法为同步方法
     *
    public synchronized void deposit(double money) {
        double newBalance = balance + money;

        try {
            Thread.sleep(10);       //模拟此业务需要处理时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        balance = newBalance;

    }
     */

    /**
     * 存入金额方法
     * 
     * 实现方式2:
     *    通过JDK1.5显示式锁机制,为每个银行账户创建一个锁对象,在存款操作时进行加锁和解锁的操作。
     */
    public void deposit(double money) {
        accountLock.lock();         //加锁

        double newBalance = balance + money;

        try {
            Thread.sleep(10);       //模拟此业务需要处理时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        balance = newBalance;

        accountLock.unlock();       //解锁

    }


    /**
     * 获得账户金额
     */
    public double getBalance() {
        return balance;
    }

}

/**
 * 存钱线程类
 */
class MoneyThread implements Runnable {

    private Account account;        //存入账户

    private double money;           //存入金额


    public MoneyThread(Account account, double money) {
        this.account = account;
        this.money = money;
    }

    @Override
    public void run() {
        account.deposit(money);
    }

}

synchronized 实现两个线程交替执行

package com.example.lum.myapplicationthread;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import java.util.concurrent.ThreadLocalRandom;

public class MainActivity extends AppCompatActivity {

    private  static  int num = 0;
    Object lock = new Object();  //定义任意对象作为锁对象
    private boolean islocked = false;   //定义一个boolean的变量
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new ThreadZreo().start(); //创建打印 0 的线程
        new ThreadOne().start();//创建打印 1 的线程

    }

    public  class  ThreadZreo extends Thread {
        @Override
        public void  run() {
            while(num++ < 20) {
                synchronized (lock) {// 将要同步的代码放到 synchronized lock 方法里,同一个lock 对象只能一时间被一个synchronized 方法所拥有
                    if (islocked) {    //判断是否上锁
                        try {
                            lock.wait();   //将这个线程等待,允许别的线程拥有 lock 锁对象, 可以被 唤醒
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        System.out.println("我是 0 线程");
                        islocked = true;   //把自己给 wait
                        lock.notifyAll(); //唤醒拥有 lock  锁对象的 wait  线程
                    }

                }
            }

        }
    }


    public class ThreadOne extends  Thread {
        @Override
        public void run () {
            while (num++ < 20) {
                synchronized (lock) {
                    if (islocked) {
                        System.out.println("我是 1 线程");
                        islocked = false;   //把自己给 wait
                        lock.notifyAll(); //唤醒拥有 lock  锁对象的 wait  线程
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

            }
        }
    }
}

注意事项
1)synchronized (lock) 其中锁对象,一次只能在一个 synchronized 方法里调用
当一个 synchronized 方法阻塞,并且没有释放 lock 对象,则 另一个 synchronized ()方法无法执行
2) lock.wait() 本线程等待,别的synchronized (lock) 线程运行 。lock.wait(2000);表示等待2s后执行下面代码,期间可被唤醒。
3)lock.notifyAll() 可以唤醒 在lock 对象上 wait 的所有线程
4)lock.wait() lock.notifyAll() 都必须在 synchronized (lock ) {} 函数之中
即使单纯的唤醒操作

synchronized (lock ) {
lock.notifyAll();
}

你可能感兴趣的:(Java)