1、之前有做过打印图形的程序,现在要通过两个线程对象打印出三角形和矩形,要求两
个图形不能错乱。
三角形Thread:
public class SanjiaoThread implements Runnable{
private int hang=5;
private Object o ;
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (o) {
for (int i = 0; i < hang; i++) {
for (int j = 0; j < hang-i-1; j++) {
System.out.print(" ");
}
for (int j = 0; j < 2*i+1; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
public int getHang() {
return hang;
}
public void setHang(int hang) {
this.hang = hang;
}
public Object getO() {
return o;
}
public void setO(Object o) {
this.o = o;
}
}
矩形Thread:
public class JuXingThread implements Runnable{
private Object o ;
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (o) {
SanjiaoThread st = new SanjiaoThread();
for (int i = 0; i < st.getHang(); i++) {
for (int j = 0; j < st.getHang()*2; j++) {
System.out.print("*");
}
System.out.println();
}
}
}
public Object getO() {
return o;
}
public void setO(Object o) {
this.o = o;
}
}
测试类:
public class Test02 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Object o = new Object();
SanjiaoThread st = new SanjiaoThread();
st.setO(o);
Thread t = new Thread(st,"三角形: ");
JuXingThread jt = new JuXingThread();
jt.setO(o);
Thread t1 =new Thread(jt,"矩形: ");
t.start();
t1.start();
}
}
通常可以在线程类里面定义要锁定的资源对象,通过主线程中创建该资源对象,通过赋
值给哪个线程,哪个线程获得资源的拥有权进行操作。
2、有一个男生叫晓军,在双十一这天要取银行卡里5000中的3000,然而他媳妇正好购物
车中放了3000块钱的包包和衣服,俩人同时取钱,要求一人取出后另一个人账号小于
3000取不出来,解决线程同步问题。
线程类:
public class QuqianRun1 extends Thread{
private static Integer money=5000;
boolean flag = false;
@Override
public void run() {
synchronized (money) {
if(flag)
{
if(money>3000)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+": 能取钱了!");
money-=3000;
System.out.println(Thread.currentThread().getName()+"剩余:"+money);
}
}else{
if(money>3000)
{
System.out.println(Thread.currentThread().getName()+": 能花钱了!");
money-=3000;
System.out.println(Thread.currentThread().getName()+"剩余:"+money);
}
}
}
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
测试类:
public class Test04 {
public static void main(String[] args) {
// TODO Auto-generated method stub
QuqianRun1 qr = new QuqianRun1();
qr.setName("晓军");
qr.setFlag(true);
QuqianRun1 qr1 = new QuqianRun1();
qr1.setName("他媳妇");
qr1.setFlag(false);
qr.start();
qr1.start();
}
}
这个是随机运行,两个线程不一定轮到谁,多试几次。。结果就会不一样。
3、电影票购买,分为到店买和网上购买,最近上映的《奇异博士》,晚场票量一共500
张,两种购买方式不冲突,低于0张不可购买。
线程类:
import java.util.Scanner;
public class DianYingPiao extends Thread{
// private Object o;
private static Integer count=500;
private boolean b =true;
private int zhang =0;
@Override
public void run() {
// TODO Auto-generated method stub
if(b)
{
synchronized (count) {
System.out.println("输入到店要买的张数:");
Scanner sc = new Scanner(System.in);
zhang =sc.nextInt();
if(count>=zhang)
{
count-=zhang;
System.out.println("成功购买"+zhang+"张电影票!剩余"+count+"张。");
}
else{
System.out.println("余量不足!");
}
}
}else
{
synchronized (count) {
System.out.println("输入网上要买的张数:");
Scanner sc = new Scanner(System.in);
zhang =sc.nextInt();
if(count>=zhang)
{
count-=zhang;
System.out.println("成功购买"+zhang+"张电影票!剩余"+count+"张。");
}
else{
System.out.println("余量不足!");
}
}
}
}
public boolean isB() {
return b;
}
public void setB(boolean b) {
this.b = b;
}
// public Object getO() {
// return o;
// }
// public void setO(Object o) {
// this.o = o;
// }
}
测试类:
public class Test07 {
public static void main(String[] args) {
// TODO Auto-generated method stub
// Object o = new Object();
DianYingPiao dyp1 = new DianYingPiao();
DianYingPiao dyp2 = new DianYingPiao();
dyp2.setB(false);
// dyp1.setO(o);
// dyp2.setO(o);
dyp1.start();
dyp2.start();
}
}
线程类和测试类中注释的地方第二种解决线程同步问题方法,通过主类设置给哪个线程
上锁资源进行操作。使用这种方式需要在synchronized中改成object对象o,而不是
count。
4.科学家吃饭问题,5个科学家吃饭,每个人只有一只筷子,要想吃到饭,必须用两只筷
子,但是如果每个人都要等其中 一个人贡献出来自己的筷子,都吃不上饭,只要有一个
人贡献出来,大家都可以吃到饭。这就是科学家吃饭问题,这里为了更好演示,举例2个
人吃饭。
第二个人的线程:
public class Thread2 extends Thread{
private Object o1;
private Object o2;
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (o2) {
System.out.println("我已经有我一只筷子了,再给我一只呗!");
synchronized (o1) {
System.out.println("我终于要开吃啦!");
o1.notify();//唤醒之前的线程wait方法。使其获得时间片。
}
}
}
第一个人的线程:
public class Thread1 extends Thread{
private Object o1;
private Object o2;
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (o1) {
try {
o1.wait();//放在synchronized结构内使用。将o1所有权给释放给下个线程
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("给我筷子,你哥我要吃饭!");
synchronized (o2) {
System.out.println("终于吃到饭了!");
}
}
}
public Thread1(Object o1, Object o2) {
super();
this.o1 = o1;
this.o2 = o2;
}
}
测试类:
public class Test06 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Object o1 = new Object();
Object o2 = new Object();
Thread1 t1 = new Thread1(o1, o2);
Thread2 t2 = new Thread2(o1, o2);
t1.start();
t2.start();
}
}
这样是第一个人先贡献自己的筷子,永远第二个人先吃饭,然后第一个人再吃。
5、介绍一下好玩的类TimerTast(计时器任务)—Timer(计时器),通过创建Timer
类对象调用schedule方法,来定时做一些事情,例如闹钟嘛、、
代码:
import java.awt.Toolkit;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Timermain {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Timer timer = new Timer();
Date time = new Date(System.currentTimeMillis()+5000);
timer.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
Toolkit.getDefaultToolkit().beep();
}
}, time, 500);
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}, 5000, 600);
Thread.sleep(10000);
timer.cancel();
}
}
schedule(TimerTask task, Date firstTime, long period) ;
这个方法中第一个是TimerTask的一个对象,第二个参数是开始的时间,第三个参数是
间隔时间。
可以是向上面的匿名内部类之间在main中创建task,也可以在外面建一个TimerTast
类,传入其对象都可以。匿名内部类在Android中经常用到,方便。
run方法就是到点时要执行的操作,Toolkit.getDefaultToolkit().beep();是调用电脑系
统默认声音。。