视频整理:
问题:通过多线程解决小朋友分苹果的问题:一共有5个苹果,2个小朋友同时拿苹果,每次拿一个,拿完为止
package org.jsoft.Thread;
public class ThreadApple implements Runnable{
private int apple = 5;
boolean getApple(){
if(apple > 0 ){
apple--;
System.out.println(Thread.currentThread().getName() + "拿了一个苹果,还剩下" + apple +"个苹果");
return true;
}
return false;
}
//线程体
@Override
public void run() {
boolean flag = getApple();
while(flag){
flag = getApple();
}
System.out.println(Thread.currentThread().getName() + "线程结束了");
}
public static void main(String[] args) {
ThreadApple thread = new ThreadApple();
Thread t1 = new Thread(thread);
t1.setName("第1个小朋友");
Thread t2 = new Thread(thread);
t2.setName("第2个小朋友");
t1.start();
t2.start();
}
/*控制台输出:第1个小朋友拿了一个苹果,还剩下3个苹果
第2个小朋友拿了一个苹果,还剩下3个苹果
第1个小朋友拿了一个苹果,还剩下2个苹果
第2个小朋友拿了一个苹果,还剩下1个苹果
第1个小朋友拿了一个苹果,还剩下0个苹果
第2个小朋友线程结束了
第1个小朋友线程结束了*/
//但是这样存在线程安全问题
}
线程安全问题及解决:
package org.jsoft.Thread;
public class ThreaAppleSafeTest implements Runnable{
/*线程安全问题:因为多个线程访问共享一个资源就容易发生线程安全问题,容易线程并发
*那么此时就需要一个锁,就像坐火车一样,卫生间有人占用就要上锁,那么此时也就需要一个共同锁
*(即两者共同的资源:ThreaAppleSafeTest),这样就解决了线程安全问题
**/
private int apple = 5;
boolean getApple(){
synchronized(this){//this指共同的资源
if(apple > 0 ){
apple--;
//在上一个测试例子上加上Thread.sleep()
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿了一个苹果,还剩下" + apple +"个苹果");
return true;
}
}
return false;
}
//线程体
@Override
public void run() {
boolean flag = getApple();
while(flag){
flag = getApple();
}
System.out.println(Thread.currentThread().getName() + "线程结束了");
}
public static void main(String[] args) {
ThreaAppleSafeTest thread = new ThreaAppleSafeTest();
Thread t1 = new Thread(thread);
t1.setName("第1个小朋友");
Thread t2 = new Thread(thread);
t2.setName("第2个小朋友");
t1.start();
t2.start();
}
/*
*
* 出现线程安全问题时控制台输出:(用了Thread.sleep(1000),但是没有用同步锁的时候)
* 第1个小朋友拿了一个苹果,还剩下3个苹果
第2个小朋友拿了一个苹果,还剩下2个苹果
第1个小朋友拿了一个苹果,还剩下1个苹果
第2个小朋友拿了一个苹果,还剩下0个苹果
第2个小朋友线程结束了
第1个小朋友拿了一个苹果,还剩下0个苹果
第1个小朋友线程结束了
*当设置同步锁了以后就解决了:
* 第1个小朋友拿了一个苹果,还剩下4个苹果
第2个小朋友拿了一个苹果,还剩下3个苹果
第1个小朋友拿了一个苹果,还剩下2个苹果
第2个小朋友拿了一个苹果,还剩下1个苹果
第2个小朋友拿了一个苹果,还剩下0个苹果
第1个小朋友线程结束了
第2个小朋友线程结束了(结果是不固定的,因为不一定是哪个线程抢占了CPU的资源)
*
*/
}