



- public class Account {
- private double money;//余额
- private String cardId;//卡号
-
- public Account() {
- }
-
- public Account(double money, String cardId) {
- this.money = money;
- this.cardId = cardId;
- }
- public void drawMoney(double money){
- //先搞清楚是谁来取钱
- String name = Thread.currentThread ().getName ();
- //1.判断账户金额是否足够
- if (this.money>=money){
- System.out.println (name+"开始取钱");
- this.money-=money;
- System.out.println (name+"取钱成功后余额为"+this.money);
- }else {
- System.out.println ("未取钱余额不足");
- }
- }
-
- public double getMoney() {
- return money;
- }
-
- public void setMoney(double money) {
- this.money = money;
- }
-
- public String getCardId() {
- return cardId;
- }
-
- public void setCardId(String cardId) {
- this.cardId = cardId;
- }
- }
-
-
-
-
- public class MyThread extends Thread{
- private Account acc;
- public MyThread(Account acc,String name){
- super ( name );
- this.acc=acc;
- }
-
-
-
- @Override
- public void run() {
- // if (acc.getMoney ()>=100000.0){
- // System.out.println (Thread.currentThread ().getName ()+"开始取钱");
- // acc.setMoney (acc.getMoney ()-100000.0);
- // System.out.println (Thread.currentThread ().getName ()+"取钱成功");
- // System.out.println ( Thread.currentThread ().getName ()+"取钱后账户余额"+acc.getMoney () );
- // }else {
- // System.out.println ("账户余额不足");
- // }
-
- acc.drawMoney ( 100000.0 );
- }
-
- }
-
-
-
- public class ThreadTest {
- public static void main(String[] args) {
- //1.创建一个账户类对象代表两个人的共享账户
- Account acc = new Account ( 100000.0, "787878787877" );
- //2.创建两个线程,分别表示小明,小红,两人同时去一个账户中取钱10w
- Thread m1 = new MyThread ( acc,"小明" );
- Thread m2 = new MyThread ( acc,"小红" );
- m1.start ();
- m2.start ();
-
- }
- }


解决方案:加锁



- public class Account {
- private double money;//余额
- private String cardId;//卡号
-
- public Account() {
- }
-
- public Account(double money, String cardId) {
- this.money = money;
- this.cardId = cardId;
- }
- public void drawMoney(double money){
- //先搞清楚是谁来取钱
- String name = Thread.currentThread ().getName ();
- //1.判断账户金额是否足够
- synchronized (this) {//同步代码块上锁 推荐用共享资源作为锁(this)
- if (this.money>=money){
- System.out.println (name+"开始取钱");
- this.money-=money;
- System.out.println (name+"取钱成功后余额为"+this.money);
- }else {
- System.out.println (name+"未取钱余额不足");
- }
- }
- }
- public static void test(){ //静态方法推荐用类名上锁
- synchronized (Account.class){
-
- }
- }
-
- public double getMoney() {
- return money;
- }
-
- public void setMoney(double money) {
- this.money = money;
- }
-
- public String getCardId() {
- return cardId;
- }
-
- public void setCardId(String cardId) {
- this.cardId = cardId;
- }
- }


- public synchronized void drawMoney(double money){
- //先搞清楚是谁来取钱
- String name = Thread.currentThread ().getName ();
- //1.判断账户金额是否足够
-
- if (this.money>=money){
- System.out.println (name+"开始取钱");
- this.money-=money;
- System.out.println (name+"取钱成功后余额为"+this.money);
- }else {
- System.out.println (name+"未取钱余额不足");
- }
-
- }
3.Lock锁
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
-
- public class Account {
- private double money;//余额
- private String cardId;//卡号
- //创建一个锁对象
- private final Lock lk=new ReentrantLock ();//final 保护锁对象
-
- public Account() {
- }
-
- public Account(double money, String cardId) {
- this.money = money;
- this.cardId = cardId;
- }
-
- public void drawMoney(double money){
- //先搞清楚是谁来取钱
- String name = Thread.currentThread ().getName ();
- //1.判断账户金额是否足够
- lk.lock ();//加锁
- try {
- if (this.money>=money){
- System.out.println (name+"开始取钱");
- this.money-=money;
- System.out.println (name+"取钱成功后余额为"+this.money);
- }else {
- System.out.println (name+"未取钱余额不足");
- }
- } catch (Exception e) {
- e.printStackTrace ();
- } finally {
- lk.unlock ();//解锁
- }
-
-
- }
- public static void test(){ //静态方法推荐用类名上锁
- synchronized (Account.class){
-
- }
- }
-
- public double getMoney() {
- return money;
- }
-
- public void setMoney(double money) {
- this.money = money;
- }
-
- public String getCardId() {
- return cardId;
- }
-
- public void setCardId(String cardId) {
- this.cardId = cardId;
- }
- }



- public class ThreadTest {
- public static void main(String[] args) {
- Desk desk=new Desk ();
-
- //创建3个生产者线程
- new Thread ( ()-> {
- while (true) {
- desk.put();
- }
-
- },"厨师1" ).start ();
- new Thread ( ()-> {
- while (true) {
- desk.put();
- }
- },"厨师2" ).start ();
- new Thread ( ()-> {
- while (true) {
- desk.put();
- }
-
- },"厨师3" ).start ();
-
- //创建两个消费者线程
- new Thread(()->{
- while (true) {
- desk.get();
- }
- },"吃货1").start ();
- new Thread(()->{
- while (true) {
- desk.get();
- }
- },"吃货2").start ();
- }
- }
-
-
-
- import java.util.ArrayList;
- import java.util.List;
-
- public class Desk {
- private List
list =new ArrayList<> (); - //放包子
- //厨师1,厨师2,厨师3
- public synchronized void put() {
-
- try {
- String name = Thread.currentThread ().getName ();
- //判断是否由包子
- if(list.size ()==0){
- list.add ( name+"做的肉包子" );
- System.out.println (name+"做了个肉包子");
- Thread.sleep ( 2000 );
- //唤醒别人,等待自己,(用锁对象调用)
- this.notifyAll ();//先唤醒 后等待
- this.wait ();
- }else {
- //唤醒别人,等待自己,(用锁对象调用)
- this.notifyAll ();//先唤醒 后等待
- this.wait ();
- }
- } catch (Exception e) {
- e.printStackTrace ();
- }
-
- }
- //取包子
- //吃货1,吃货2
- public synchronized void get() {
- try {
- String name = Thread.currentThread ().getName ();
- if (list.size ()==1){
- //有包子,吃掉
- System.out.println (name+"吃了"+list.get ( 0 ));
- list.clear ();
- Thread.sleep ( 1000 );
- //唤醒别人,等待自己,(用锁对象调用)
- this.notifyAll ();//先唤醒 后等待
- this.wait ();
- }else {
- //没有包子
- //唤醒别人,等待自己,(用锁对象调用)
- this.notifyAll ();//先唤醒 后等待
- this.wait ();
- }
- } catch (Exception e) {
- e.printStackTrace ();
- }
-
- }
- }
-
-

控制线程的数量,也控制任务的数量,避免系统创建太多线程,耗费大量的系统资源。挺高系统性能。



- import java.util.concurrent.*;
-
- public class ThreadPoolTest {
- public static void main(String[] args) {
- // public ThreadPoolExecutor(int corePoolSize,
- // int maximumPoolSize,
- // long keepAliveTime,
- // TimeUnit unit,
- // BlockingQueue
workQueue) { - // this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
- // Executors.defaultThreadFactory(), defaultHandler);
- //1.通过ThreadPoolExecutor 创建一个线程池对象
- ExecutorService pool= new ThreadPoolExecutor ( 3,5,8,TimeUnit.SECONDS,
- new ArrayBlockingQueue<> ( 4 ),Executors.defaultThreadFactory (),new ThreadPoolExecutor.AbortPolicy ());
- }
-
-
-
-
- }
-
-
-


- import java.util.concurrent.*;
-
- public class Test {
- public static void main(String[] args) throws Exception {
- // //1.通过ThreadPoolExecutor 创建一个线程池对象
- // ExecutorService pool= new ThreadPoolExecutor ( 3,5,8, TimeUnit.SECONDS,
- // new ArrayBlockingQueue<> ( 4 ), Executors.defaultThreadFactory (),new ThreadPoolExecutor.AbortPolicy ());
- //1-2 通过Executors创建一个线程对象。
- ExecutorService pool = Executors.newFixedThreadPool ( 3 );//新建固定数量线程的线程池
- //计算密集型任务:核心线程数量=CPU核数+1;
- //IO密集型任务:核心线程数量=CPU核数*2;
- Executors.newSingleThreadExecutor ();//新建单个线程数量的线程池
- //2.使用线程处理Callable 任务类
- Future
f1 = pool.submit ( new MyCallable ( 100 ) );//返回未来任务对象(结果) - Future
f2 = pool.submit ( new MyCallable ( 200 ) ); - Future
f3 = pool.submit ( new MyCallable ( 300 ) ); - Future
f4 = pool.submit ( new MyCallable ( 400 ) ); -
- System.out.println ( f1.get () );
- System.out.println ( f2.get () );
- System.out.println ( f3.get () );
- System.out.println ( f4.get () );
-
-
- }
- }



- public class MyRunnable implements Runnable{
- @Override
- public void run() {
- //描述任务
- System.out.println (Thread.currentThread ().getName ()+"====>666");
- try {
- Thread.sleep ( Integer.MAX_VALUE );
- } catch (InterruptedException e) {
- e.printStackTrace ();
- }
- }
- }
-
-
- import java.util.concurrent.*;
-
- public class ThreadPoolTest {
- public static void main(String[] args) {
- // public ThreadPoolExecutor(int corePoolSize,
- // int maximumPoolSize,
- // long keepAliveTime,
- // TimeUnit unit,
- // BlockingQueue
workQueue) { - // this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
- // Executors.defaultThreadFactory(), defaultHandler);
- //1.通过ThreadPoolExecutor 创建一个线程池对象
- ExecutorService pool= new ThreadPoolExecutor ( 3,5,8,TimeUnit.SECONDS,
- new ArrayBlockingQueue<> ( 4 ),Executors.defaultThreadFactory (),new ThreadPoolExecutor.AbortPolicy ());
- Runnable target = new MyRunnable ();
- pool.execute ( target );//把任务交给线程池,线程池会自动创建一个新的线程,自动处理这个任务,自动执行。
- pool.execute ( target );
- pool.execute ( target );
- //临时线程的创建时机
- pool.execute ( target );//复用前面的核心线程执行任务
- pool.execute ( target );
- //开始进入任务队列
- pool.execute ( target );
- pool.execute ( target );
- pool.execute ( target );
- pool.execute ( target );
- //开始拒绝策略(任务队列占满)
- pool.execute ( target );//拒绝直接抛出错误
- // pool.shutdown ();//等线程池的任务全部执行完毕后,才会关闭线程池
- // pool.shutdownNow ();//立刻关闭线程池,不管任务是否执行完毕
-
-
- }
-
-
-
-
- }
-
-
-
-

- import java.util.concurrent.Callable;
-
- public class MyCallable implements Callable
{ - private int n;
-
- public MyCallable() {
- }
-
- public MyCallable(int n) {
- this.n = n;
- }
-
- @Override
- public String call() throws Exception {
- int sum=0;
- for (int i = 0; i <=n; i++) {
- sum+=i;
- }
- return Thread.currentThread ().getName ()+"求出了1-"+n+"的和是:"+sum;
- }
- }
-
-
-
- import java.util.concurrent.*;
-
- public class Test {
- public static void main(String[] args) throws Exception {
- //1.通过ThreadPoolExecutor 创建一个线程池对象
- ExecutorService pool= new ThreadPoolExecutor ( 3,5,8, TimeUnit.SECONDS,
- new ArrayBlockingQueue<> ( 4 ), Executors.defaultThreadFactory (),new ThreadPoolExecutor.AbortPolicy ());
- //2.使用线程处理Callable 任务类
- Future
f1 = pool.submit ( new MyCallable ( 100 ) );//返回未来任务对象(结果) - Future
f2 = pool.submit ( new MyCallable ( 200 ) ); - Future
f3 = pool.submit ( new MyCallable ( 300 ) ); - Future
f4 = pool.submit ( new MyCallable ( 400 ) ); -
- System.out.println ( f1.get () );
- System.out.println ( f2.get () );
- System.out.println ( f3.get () );
- System.out.println ( f4.get () );
-
-
- }
- }




人的生命周期


sleep(不会释放锁) wait(会释放锁)

一上来就加锁,没有安全感,每次只能一个线程进入访问完毕后,再关锁。线程安全,性能较差!
- public class MyRunnable implements Runnable{
- private int count;
- @Override
- public void run() {
- for (int i = 0; i <100; i++) {
-
- //悲观锁
- synchronized (this) {
- System.out.println ("count=====>"+ (++count));
- }
-
-
- }
-
- }
- }
-
-
- public class Test1 {
- public static int Number;
- public static void main(String[] args) {
- //悲观锁,乐观锁的原理
- //悲观锁:一上来就加锁,没有安全感,每次只能一个线程进入访问完毕后,再关锁。线程安全,性能较差!
- //乐观锁:一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题时才开始控制。线程安全,性能较好!
-
- //需求:1个变量,100个线程,每个线程对其加100次
- Runnable target =new MyRunnable ();
- for (int i = 1; i <=100; i++) {
- new Thread (target).start ();
- }
-
-
- }
- }
-
利用原子类实现
乐观锁:一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题时才开始控制。线程安全,性能较好!
- public class MyRunnable2 implements Runnable{
- //乐观锁 CAS算法 比较(Compare)A(and)S(修改Set) 算法
- //整数修改的乐观锁:原子类实现的
- private AtomicInteger count=new AtomicInteger ();
-
- @Override
- public void run() {
- for (int i = 0; i <100; i++) {
-
-
- System.out.println ("count=====>"+ count.incrementAndGet ());//先加1然后再返回值
-
-
- }
-
-
- public class Test2 {
-
- public static void main(String[] args) {
- //悲观锁,乐观锁的原理
- //悲观锁:一上来就加锁,没有安全感,每次只能一个线程进入访问完毕后,再关锁。线程安全,性能较差!
- //乐观锁:一开始不上锁,认为是没有问题的,大家一起跑,等要出现线程安全问题时才开始控制。线程安全,性能较好!
-
- //需求:1个变量,100个线程,每个线程对其加100次
- Runnable target =new MyRunnable2 ();
- for (int i = 1; i <=100; i++) {
- new Thread (target).start ();
- }
-
-
- }
- }