笔记:
jar
---------------
jar cvf xxx.jar -C classes/ .
进程
-----------------
进程之间内存式隔离的。内存不共享。
线程
-----------------
程序执行过程中,并发执行的代码段。
线程之间可以共享内存。
Thread : 线程类。
start() //通知cpu,可以开始执行该线程。
run() //线程具体执行的代码段。
Thread t = new Thread();
t.start();
Thread.currentThread() //得到当前的执行线程。
yield() //让线程放弃cpu的抢占权。
sleep(int mils) //让当前线程休眠指定的毫秒数.但不释放锁旗标
join //当线程执行结束后再执行另外一个线程
start //通知cpu可以启动线程
run //线程的主要方法
isDaemon(); //指定线程是否是守护线程
start(); //启动线程
notify() //选择一个监控器对象等待队列中的线程进行通知。
notifyAll() //选择所有监控器对象等待队列中的线程进行通知。
wait() //将当前线程放入监控器的等待队列中。
wait(int n ) //线程进入到等待队列后,最多等待n长时间时间一旦,自动唤醒。
线程安全:增加了同步处理。确保在同一时刻,只有一个线程执行同步代码。
同步方法使用的当前对象作为同步对象。
守护线程:
daemon setDaemon(true); //线程启动前设置
同步代码块
private static Object lock = new Object();
// 创建一个静态对象lock,lock 是锁旗标
synchronized(lock){}
//在此范围的进程同步执行 ,保证一段代码在一段时间只能有一个线程在同一执行
synchronized
//同步函数 使用的锁旗标就是当前对象----this
线程安全:
synchronized
增加了同步处理。确保在同一时刻,只有一个线程执行同步代码。
同步方法使用的当前对象作为同步对象。
静态方法可以加同步处理,使用Class作为同步对象。
例子:
案例1 打麻将
package com.work.eight;
import java.lang.Thread; //导包
class Member extends Thread{ //新建成员将线程
private String name;
private int seconds;
public Member (String name, int sec){
this.name=name;
this.seconds=sec;
}
//定义run方法
public void run(){
try{ //可能会报错,使用 try catch捕捉异常
System.out.println("玩家:"+name+"出发!");
//System.out.println(seconds*1000);
System.out.println("玩家:"+name+"到达! 用时:"+seconds+"秒!");
}
catch(Exception e){
e.printStackTrace();
}
}
}
class Demo1{
public static void main(String [] args) throws Exception{
//new 英雄
Member m1 = new Member ("成龙",5);
Member m2 = new Member ("李小龙",15);
Member m3 = new Member ("李连杰",10);
Member m4 = new Member ("赵文卓",8);
//线程开始
m1.start();
m2.start();
m3.start();
m4.start();
//等待执行
m1.join(); // join阻塞调用线程,直到该线程结束后,调用线程才能继续执行。
m2.join();
m3.join();
m4.join();
System.out.println("人到齐,开局");
}
}
运行结果:
玩家:李连杰出发!
玩家:赵文卓出发!
玩家:李小龙出发!
玩家:成龙出发!
玩家:李小龙到达! 用时:15秒!
玩家:赵文卓到达! 用时:8秒!
玩家:李连杰到达! 用时:10秒!
玩家:成龙到达! 用时:5秒!
人到齐,开局案例2 KTV
package com.work.eight;
import java.lang.Thread;
import java.util.Date;
class Box extends Thread{ //Box 线程
private String boxNo; //包厢号
private int sec;
public Box(String boxNo, int sec){ //重载构造函数
this.boxNo =boxNo;
this.sec =sec ;
}
//定义run方法
public void run(){
System.out.println(boxNo + "号包厢开始上唱歌!!!!"); //显示唱歌开始
try{ // 捕捉异常
Thread.sleep(sec*1000);
}
catch(Exception e){
}
System.out.println(boxNo + "号包厢结账----");
}
}
//创建服务员进程(守护线程)
class Waiter extends Thread {
private String name;
private int idNo;
private int sec;
public Waiter (String name ,int idNo,int sec){ //重写构造函数
this.name = name;
this.idNo = idNo;
this.sec = sec ;
}
//定义run方法
public void run(){
//间隔1秒报时一次
while(true){
try{
System.out.println(idNo+"号服务员"+name+"为您报时,现在是北京时间"+new Date());
Thread.sleep(sec*1000);
}
catch(Exception e){
}
}
}
}
class Demo2 { //创建Demo类
public static void main(String [] args){
Box bo1 = new Box("1",10) ; //新建3个box对象和一个 waiter对象
Box bo2 = new Box("2",10) ;
Box bo3 = new Box("3",5) ;
Waiter w1 =new Waiter("Kistina",66,1);
w1.setDaemon(true); //定义守护线程 Thread.setDaemon(true);
//当只有守护线程运行时,守护线程自动结束
bo1.start();
bo2.start();
bo3.start();
w1.start();
}
}
运行结果:
1号包厢开始上唱歌!!!!
3号包厢开始上唱歌!!!!
2号包厢开始上唱歌!!!!
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:29:54 CST 2016
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:29:55 CST 2016
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:29:56 CST 2016
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:29:57 CST 2016
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:29:58 CST 2016
3号包厢结账----
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:29:59 CST 2016
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:30:00 CST 2016
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:30:01 CST 2016
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:30:02 CST 2016
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:30:03 CST 2016
1号包厢结账----
2号包厢结账----
66 号服务员 Kistina 为您报时,现在是北京时间Thu May 17 10:30:04 CST 2016案例3 售票
package com.work.eight;
class Saler extends Thread{ //新建 售票员线程
private String name ;
private static int tickets = 100 ; //使该变量在类的所有实例中共享,否则每个售票员都卖100张
private static Object lock = new Object() ; // 新建一个静态对象 lock lock 是锁旗标
public Saler(String name ){ //重载构造函数
this.name =name ;
}
public void run (){ //run函数
while(tickets >0){ //while 函数
synchronized(lock) { //同步代码块 只允许获得锁旗标的进入
int temp = tickets ;
tickets = temp -1;
System.out.println(name+":票号:T"+temp);
}
yield(); //谦让,释放对cpu的抢占权以及对 锁旗标的锁定
}
}
}
class TicketDemo{
public static void main (String[] args){
Saler s1 = new Saler("乘客1");
Saler s2 = new Saler("乘客2");
s1.start();
s2.start();
}
}
结果(部分):
乘客1:票号:T100
乘客1:票号:T99
乘客1:票号:T98
乘客1:票号:T97
乘客2:票号:T96
乘客2:票号:T95
乘客2:票号:T94
乘客2:票号:T93作业:
1.5辆汽车过山洞,依次经过山洞。每辆车通过山洞花费10秒,使用多线程实现。
代码
package com.work.eight;
class Car extends Thread{
Hole hole =new Hole ("山洞",1);
private String brand; //品牌
private int carNo; //车号
private int sec; //过山洞时间
public Car(int carNo,String brand,int sec){
this.brand=brand;
this.carNo=carNo;
this.sec=sec;
}
public void run(){
synchronized(hole){ //同步代码块
System.out.println("第 "+carNo+"辆车 "+brand+" 驶入 "+hole.getHolename()+" 路程 "+hole.getHolelong()+"公里");
try{
Thread.sleep(sec*1000);
System.out.println("第 "+carNo+"辆车 "+brand+" 驶出山洞 用时"+sec+"秒!");
}
catch(Exception e){}
}
}
}
class Hole {
private String holename; //山洞名字
private int holelong; //路程
public Hole(String holename, int holelong){
this.holename=holename;
this.holelong=holelong;
}
public String getHolename() {
return holename;
}
public void setHolename(String holename) {
this.holename = holename;
}
public int getHolelong() {
return holelong;
}
public void setHolelong(int holelong) {
this.holelong = holelong;
}
}
class CrossHoleDemo{
public static void main(String[] args) throws Exception{
//定义汽车
Car c1 = new Car(1,"奔驰",10);
Car c2 = new Car(2,"宝马",10);
Car c3 = new Car(3,"玛莎拉蒂",10);
Car c4 = new Car(4,"法拉利",10);
Car c5 = new Car(5,"布加迪",10);
//每个函数按照顺序来执行
c1.start();
c1.join();
c2.start();
c2.join();
c3.start();
c3.join();
c4.start();
c4.join();
c5.start();
c5.join();
}
}
运行结果:
第 1辆车 奔驰 驶入 山洞 路程 1公里
第 1辆车 奔驰 驶出山洞 用时10秒!
第 2辆车 宝马 驶入 山洞 路程 1公里
第 2辆车 宝马 驶出山洞 用时10秒!
第 3辆车 玛莎拉蒂 驶入 山洞 路程 1公里
第 3辆车 玛莎拉蒂 驶出山洞 用时10秒!
第 4辆车 法拉利 驶入 山洞 路程 1公里
第 4辆车 法拉利 驶出山洞 用时10秒!
第 5辆车 布加迪 驶入 山洞 路程 1公里
第 5辆车 布加迪 驶出山洞 用时10秒!2.
用多线程模拟蜜蜂和熊的关系。
蜜蜂是生产者,熊是消费者。蜜蜂生产蜂蜜是累加的过程,熊吃蜂蜜是批量(满100吃掉)的过程。
生产者和消费者之间使用通知方式告知对方。注意不能出现死锁的现象。
代码:
package com.work.eight;
class Bear extends Thread{
private FengMi fengmi;
private String bearname;
public Bear(FengMi fengmi,String bearname){
this.fengmi=fengmi;
this.bearname=bearname;
}
public void run(){
while(true){
synchronized(fengmi){
if (fengmi.getFemgminum()<100) {
try {
fengmi.wait();
}
catch (Exception e){
}
}
else if(fengmi.getFemgminum()>=100&&fengmi.getFemgminum()%100==0){
fengmi.ChiFemgmi();
System.out.println("100 个蜂蜜被"+bearname+"吃掉,剩余"+fengmi.getFemgminum()+"个蜂蜜");
try{
fengmi.notifyAll();
}
catch(Exception e){
}
}
}
yield();
}
}
}
class FengMi {
private static int femgminum=0; //蜜罐中蜂蜜数量
private final int femgminumMax=500; //蜜罐中蜂蜜数量上限
public static int getFemgminum() {
return femgminum;
}
public int getFemgminum1() {
return femgminumMax;
}
public int getFemgminumMax() {
return femgminumMax;
}
public void CreateFemgmi() { //生产蜂蜜
this.femgminum += 1;
}
public void ChiFemgmi() { //吃蜂蜜
this.femgminum -=100;
}
}
class Bee extends Thread{
private FengMi fengmi;
private String beename;
public Bee(FengMi fengmi,String beename){
this.fengmi=fengmi;
this.beename=beename;
}
public void run(){
int i=1;
while(true){
synchronized(fengmi){
if(fengmi.getFemgminum()<fengmi.getFemgminumMax()&&fengmi.getFemgminum()>=0){
if (fengmi.getFemgminum()%100==0){
try{
System.out.println("蜂蜜采集好了,目前一共"+fengmi.getFemgminum()+"个蜂蜜,熊可以来采了");
fengmi.CreateFemgmi();
fengmi.notifyAll();
Thread.sleep(50);
}
catch(Exception e){
}
}
else {
fengmi.CreateFemgmi();
System.out.println("蜂蜜采集好了,目前一共"+fengmi.getFemgminum()+"个蜂蜜");
try{
fengmi.notifyAll();
Thread.sleep(50);
}
catch(Exception e){
}
}
}
else if(fengmi.getFemgminum()>=fengmi.getFemgminumMax()){
System.out.println("蜂蜜满了");
try{
fengmi.wait();
}
catch(Exception e){
}
}
}
i++;
yield();
}
}
}
class BeeBearModel{
public static void main(String[] args){
FengMi fengmi=new FengMi();
Bear bear1=new Bear(fengmi,"Bear1");
Bee bee=new Bee(fengmi,"Bee1");
bear1.start();
bee.start();
}
}结果(部分):
蜂蜜采集好了,目前一共95个蜂蜜
蜂蜜采集好了,目前一共96个蜂蜜
蜂蜜采集好了,目前一共97个蜂蜜
蜂蜜采集好了,目前一共98个蜂蜜
蜂蜜采集好了,目前一共99个蜂蜜
蜂蜜采集好了,目前一共100个蜂蜜
100 个蜂蜜被Bear1吃掉,剩余0个蜂蜜
蜂蜜采集好了,目前一共0个蜂蜜,熊可以来采了
蜂蜜采集好了,目前一共2个蜂蜜
蜂蜜采集好了,目前一共3个蜂蜜
蜂蜜采集好了,目前一共4个蜂蜜
蜂蜜采集好了,目前一共5个蜂蜜
本文出自 “11138113” 博客,请务必保留此出处http://11148113.blog.51cto.com/11138113/1775005
原文:http://11148113.blog.51cto.com/11138113/1775005