练习题
(1)已知有四根线程,int j=0;2根线程做相加,每次对j加3;另2根线程做相减,每次对j减4;
要求:
分别写两个同步的方法(f1(),f2())
调用时,只有两根线程,但要用for来变成四根线程;
package com.xinbo.thread;
public class Test09 {
/**
* (1)已知有四根线程,int j=0;2根线程做相加,每次对j加3;
* 另2根线程做相减,每次对j减4;
要求:
分别写两个同步的方法(f1(),f2())
调用时,只有两根线程,但要用for来变成四根线程;
*/
int j=0;
public synchronized void f1(){
j+=3;
System.out.println(Thread.currentThread().getName()+":"+j);
}
public synchronized void f2(){
j-=4;
System.out.println(Thread.currentThread().getName()+":"+j);
}
class A extends Thread{
@Override
public void run() {
for(int i=0;i<5;i++){
f1();
}
}
}
class B extends Thread{
@Override
public void run() {
try {
Thread.sleep(1000);
for(int i=0;i<5;i++){
f2();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Test09 t=new Test09();
for(int i=0;i<2;i++){
Test09.A a=t.new A();
Test09.B b=t.new B();
a.start();b.start();
}
//本例用了同步方法,将先调用的对象用同步方法锁定,
//所以在两个同步方法内谁先拿到同步锁,谁就先把整个代码块执行完
}
}
练习2:
已知有三个对象o1,o2,o3;o3唤醒o2,o2唤醒o1;
要求:
(1)o2,o1里面都有wait();o2,o3里面有notify();
(2)已知有一个变量a=3;当第一次被唤醒时,a加上2;当第二次再被唤醒时,在原来的基础上a再加10;
package com.xinbo.thread;
public class Test01 {
/**
* 3、已知有三个对象o1,o2,o3;o3唤醒o2,o2唤醒o1;
要求:
(1)o2,o1里面都有wait();o2,o3里面有notify();
(2)已知有一个变量a=3;当第一次被唤醒时,a加上2;当第二次再被
唤醒时,在原来的基础上a再加10;
*/
static Object o1=new Object();
static Object o2=new Object();
static Object o3=new Object();
static int i=3;
static class A extends Thread{
@Override
public void run() {
synchronized (o1) {
try {
o1.wait();
i+=2;
System.out.println("第一次输出i="+i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
static class B extends Thread{
@Override
public void run() {
synchronized (o2) {
try {
Thread.sleep(200);//目的让O1先执行
synchronized (o1) {
o1.notify();
}
o2.wait();
i+=10;
System.out.println("第二次输出为i="+i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
static class C extends Thread{
@Override
public void run() {
synchronized (o3) {
try {
Thread.sleep(1000);//为了让O2或o1先执行,让他们先锁住
synchronized (o2) {
o2.notify();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
A a=new A();
B b=new B();
C c=new C();
a.start();
b.start();
c.start();
}
}
3.练习
已知有一个航空公司,每天都要售10张票,假设平均每5
秒钟卖出去一张(一人只限一张),请用同步的方法来做,并
打印具体信息(信息,日期等)。(银行的存取款)
SimpleDateFormat sdf=new SimpleDateFormat("y年M月d日 HH:mm:ss");
package com.xinbo.thread1;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
Me m;
Scanner s=new Scanner(System.in);
for(int i=0;i<10;i++){
try {
Thread.sleep(2000);
System.out.println("请输入姓名:");
String name=s.nextLine();
m=new Me("姓名:",name);
m.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Me extends Thread{
String x;
static int num;
SimpleDateFormat sdf=new SimpleDateFormat("y年M月d日 HH:mm:ss");
public Me(String name,String x){
super(name);
this.x=x;
}
@Override
public void run() {
f(x);
}
public synchronized void f(String name){
try {
num++;
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+name+",买第"+num+"张"+"打印日期:"+sdf.format(new Date())+",当前还剩余票数"+(10-num)+"张");
System.out.println("-----------------------------------------------------------------------");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
转载于:https://blog.51cto.com/10079391/1686776