例一:线程同步问题示例(试衣)
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
注:此方法可能会出现死锁,在以后的有关线程程序设计中,死锁不可消除,仅可避免