(執行緒三)執行緒同步問題示例
例一:執行緒同步問題示例(試衣)
public class ThreadDemo06 {
public static void main(String[] args) {
Market market=new Market();
MyTask m1=new MyTask(market);
MyTask m2=new MyTask(market);
Thread t1=new Thread(m1);
Thread t2=new Thread(m2);
t1.start();
t2.start();
}
}
class Market{
public void tryPut() {
System.out.println("進入商場");
System.out.println("開始挑衣服");
synchronized (this) {
System.out.println("進入試衣間");
for(int i=1;i<=5;i++) {
System.out.println("試衣第"+i+"步");
}
System.out.println("試衣結束");
System.out.println("走出試衣間");
}
System.out.println("走出商場");
}
}
class MyTask implements Runnable{
private Market market;
public MyTask(Market market) {
this.market=market;
}
public void run() {
market.tryPut();
}
}
執行結果:
進入商場
開始挑衣服
進入商場
開始挑衣服
進入試衣間
試衣第1步
試衣第2步
試衣第3步
試衣第4步
試衣第5步
試衣結束
走出試衣間
走出商場
進入試衣間
試衣第1步
試衣第2步
試衣第3步
試衣第4步
試衣結束
走出試衣間
走出商場
可見如果要實現執行緒同步需要給須同步的程式碼上鎖
例二:執行緒同步問題示例(取豆子)
class Table{
private int beans=5;
public int getBeans() {
System.out.println("開始取豆子");
int result=0;
synchronized (this) {
result=beans--;
System.out.println("取走一顆豆子");
}
if(result<0) {
throw new RuntimeException("豆子沒有啦");
}else {
System.out.println("豆子還剩:"+result);
}
return result;
}
}
public class ThreadDemo07 {
public static void main(String[] args) {
Table t=new Table();
Thread t1=new Thread() {
public void run() {
while(true) {
System.out.println("t1:"+t.getBeans());
}
}
};
Thread t2=new Thread() {
public void run() {
while(true) {
System.out.println("t2:"+t.getBeans());
}
}
};
t1.start();
t2.start();
}
}
執行結果:
開始取豆子
取走一顆豆子
開始取豆子
取走一顆豆子
豆子還剩:4
豆子還剩:5
t2:4
開始取豆子
取走一顆豆子
豆子還剩:3
t2:3
開始取豆子
取走一顆豆子
豆子還剩:2
t2:2
開始取豆子
取走一顆豆子
豆子還剩:1
t2:1
開始取豆子
取走一顆豆子
豆子還剩:0
t2:0
開始取豆子
取走一顆豆子
t1:5
開始取豆子
取走一顆豆子
Exception in thread "Thread-1" Exception in thread "Thread-0" java.lang.RuntimeException: 豆子沒有啦
at com.hyxy0915.Table.getBeans(ThreadDemo07.java:12)
at com.hyxy0915.ThreadDemo07$2.run(ThreadDemo07.java:37)
java.lang.RuntimeException: 豆子沒有啦
at com.hyxy0915.Table.getBeans(ThreadDemo07.java:12)
at com.hyxy0915.ThreadDemo07$1.run(ThreadDemo07.java:30)
例三:執行緒同步問題示例(計算器)
public class ThreadDemo08 {
public static void main(String[] args) {
Computer c=new Computer(30,15);
Task1 ta1=new Task1(c);
Task2 ta2=new Task2(c);
Thread t1=new Thread(ta1);
Thread t2=new Thread(ta2);
t1.start();
t2.start();
}
}
class Computer{
int a;
int b;
int result=0;
public Computer(int a,int b) {
this.a=a;
this.b=b;
}
public synchronized int add(int a,int b) {
result=a+b;
System.out.println(result);
return result;
}
public synchronized int substract(int a,int b) {
result=a-b;
System.out.println(result);
return result;
}
}
class Task1 implements Runnable{
Computer c;
public Task1(Computer c) {
this.c=c;
}
public void run() {
c.add(c.a,c.b);
}
}
class Task2 implements Runnable{
Computer c;
public Task2(Computer c) {
this.c=c;
}
public void run() {
c.substract(c.a,c.b);
}
}
public class ThreadDemo08 {
public static void main(String[] args) {
Computer c=new Computer(30,15);
Task1 ta1=new Task1(c);
Task2 ta2=new Task2(c);
Thread t1=new Thread(ta1);
Thread t2=new Thread(ta2);
t1.start();
t2.start();
}
}
class Computer{
int a;
int b;
int result=0;
public Computer(int a,int b) {
this.a=a;
this.b=b;
}
public synchronized int add(int a,int b) {
result=a+b;
System.out.println(result);
return result;
}
public synchronized int substract(int a,int b) {
result=a-b;
System.out.println(result);
return result;
}
}
class Task1 implements Runnable{
Computer c;
public Task1(Computer c) {
this.c=c;
}
public void run() {
c.add(c.a,c.b);
}
}
class Task2 implements Runnable{
Computer c;
public Task2(Computer c) {
this.c=c;
}
public void run() {
c.substract(c.a,c.b);
}
}
執行結果:45 15
作業一:三個執行緒分別取五個數,第一個為一到五,第二個為六到十,第三個為十一到十五,以此類推,取至75停止
public class ThreadHomework {
public static void main(String[] args) {
T t0=new T(0);
T t1=new T(1);
T t2=new T(2);
t0.start();
t1.start();
t2.start();
}
}
class T extends Thread{
private int version;
private static int num=0;
public static Object obj=new Object();
public T(int version) {
this.version=version;
}
public void run() {
while(num<75) {
print();
}
}
public void print() {
synchronized (obj) {
if(num%15/5==version&&num<75) {
num++;
System.out.println(version+":"+num);
}
}
}
}
執行結果:結果過於冗長,不再舉例
作業二:模擬倉庫消費者及生產者
public class ThreadHomework1 {
public static void main(String[] args) {
WareHourse wh=new WareHourse(80);
Consume c=new Consume(wh,20);
Product p=new Product(wh,30);
c.start();
p.start();
}
}
class WareHourse{
private static final int max_capacity=100;
private int surplus_capacity;
public WareHourse(int surplus_capacity) {
this.surplus_capacity=surplus_capacity;
}
public synchronized void consume(int needNum) {
while(needNum>surplus_capacity) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消費方法");
surplus_capacity-=needNum;
System.out.println("倉庫剩餘:"+surplus_capacity);
this.notifyAll();
}
public synchronized void product(int proNum) {
while(proNum+surplus_capacity>max_capacity) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生產方法");
surplus_capacity+=proNum;
System.out.println("倉庫剩餘:"+surplus_capacity);
this.notifyAll();
}
}
class Consume extends Thread{
private WareHourse wh;
private int needNum;
public Consume(WareHourse wh,int needNum) {
this.wh=wh;
this.needNum=needNum;
}
public void run() {
wh.consume(needNum);
}
}
class Product extends Thread{
private WareHourse wh;
private int proNum;
public Product(WareHourse wh,int proNum) {
this.wh=wh;
this.proNum=proNum;
}
public void run() {
wh.product(proNum);
}
}
執行結果: 消費方法
倉庫剩餘:60
生產方法
倉庫剩餘:90
注:此方法可能會出現死鎖,在以後的有關執行緒程式設計中,死鎖不可消除,僅可避免