0 项目,包,文件,类
Mytest是自己建的java工程,包含src和JRE System Libery。其中src是存放自己的代码的地方,JRE包含程序运行时所需要的各种文件;在src下包含Test包,一个包就是许多.java文件的合集,src下可以有很多的包,在写程序时Import 包名表明用这个包;一个包下可以有很多的.java文件,在该文件下写代码,一个文件下只能有一个public类。
1 定义学生类并调用及static的事项
1 package Test;//在Test包下 2 3 public class Main{ 4 //快速生成main方法,写main然后alt+/便可快速生成 5 public static void main(String[] args) { 6 //直接通过类调用,静态所修饰的成员优先于对象随着类的加载而加载 7 Student.graduatefrom="abcd"; 8 //在创建时直接初始化 9 Student s=new Student("zhangsan",18,"M"); 10 11 //也可以调用get和set方法 12 Student s2=new Student(); 13 s2.setAge(13); 14 s2.setGednder("W"); 15 s2.setName("小李"); 16 //显示出来 17 s.show(); 18 s2.show(); 19 20 //这样显示的是s和s2的地址 21 System.out.println(s); 22 System.out.println(s2); 23 } 24 } 25 26 //在一个文件下只能有一个public类 27 class Student{ 28 //类中使用私有的成员变量做到封装思想 29 private String name; 30 private int age; 31 private String gednder; 32 //当这两个人都毕业于同一院校时,每次构建对象便要重新赋值比较麻烦,可以考虑赋值一次便能让这个类的所有对象都共享。 33 static String graduatefrom; 34 35 //无参构造,只要人为定义一个构造方法后java便不会再自动生成默认构造方法 36 public Student(){} 37 38 //有参构造可以用来初始化成员变量,右键--source可以自动生成构造方法,get set方法 39 public Student(String name, int age, String gednder) { 40 super(); 41 //方法内部的变量名和类中成员变量名字相同,用this,this其实是Student对象的地址 42 this.name = name; 43 this.age = age; 44 this.gednder = gednder; 45 } 46 47 //生成get和set方法因为成员变量使用private修饰无法在其他类中访问,,同过get set方法便可以读写这就是封装的思想 48 public String getName() { 49 return name; 50 } 51 52 public void setName(String name) { 53 this.name = name; 54 } 55 56 public int getAge() { 57 return age; 58 } 59 60 public void setAge(int age) { 61 this.age = age; 62 } 63 64 public String getGednder() { 65 return gednder; 66 } 67 68 public void setGednder(String gednder) { 69 this.gednder = gednder; 70 } 71 72 public void show(){ 73 //输出syso快捷键alt+/ 74 System.out.println(name+" "+age+" "+" "+gednder+" "+graduatefrom); 75 } 76 77 } 78 79 /*关于静态方法的几点注意 80 * 1:静态方法只能调用静态方法 81 * 2:非静态方法可以都调用 82 * 3:静态方法随着类加载而加载优先于对象加载因此没有this指针 83 * 84 */
2 模拟发牌
了解ArrayList,Collections的使用
1 package Test; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 6 /* 7 *模拟发牌 8 * 建牌 9 * 洗牌 10 * 发牌 11 */ 12 public class Main { 13 public static void main(String[] args) { 14 15 16 //牌由花色和数字组成 17 String[] color = {"梅花","黑桃","方片","红桃"}; 18 //数字 19 String[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"}; 20 21 //装牌 22 ArrayList<String> box = new ArrayList<String>(); 23 for (int i = 0; i < color.length; i++) { 24 for (int j = 0; j < num.length; j++) { 25 box.add(color[i] + num[j]); 26 } 27 } 28 box.add("大王"); 29 box.add("小王"); 30 31 //shuffle随机置换元素顺序 32 Collections.shuffle(box); 33 34 35 //发牌实质就是创建三个数组然后存入,可以用汉语作为对象名 36 ArrayList<String> 李大狗= new ArrayList<String>(); 37 ArrayList<String> 李二狗 = new ArrayList<String>(); 38 ArrayList<String> 李三狗 = new ArrayList<String>(); 39 40 for (int i = 0; i < box.size() - 3; i++) { 41 if(i % 3 == 0) { 42 李大狗.add(box.get(i)); 43 } 44 else if(i % 3 == 1) { 45 李二狗.add(box.get(i)); 46 } 47 else if(i % 3 == 2) { 48 李三狗.add(box.get(i)); 49 } 50 } 51 52 System.out.println("李大狗:" + 李大狗); 53 System.out.println("李二狗:" + 李二狗); 54 System.out.println("李三狗:" + 李三狗); 55 56 57 System.out.println("底牌"); 58 59 for(int x = box.size() - 3;x < box.size();x++) { 60 System.out.println(box.get(x)); 61 } 62 } 63 64 }
3 多线程火车票
Main.class
1 package Test; 2 3 /*模拟火车票售票 4 * 使用多线程模拟多个窗口售票 5 * 当售票完后火车站同样欢迎,因此无需关闭 6 */ 7 8 public class Main{ 9 public static void main(String[] args) { 10 //创建Runnable实现对象 11 TicketThread tt =new TicketThread(); 12 //创建线程对象,有多个线程,因为ticket是一定,所以创建线程时都要使用tt 13 Thread t=new Thread(tt); 14 t.setName("窗口1"); 15 Thread t2=new Thread(tt); 16 t2.setName("窗口2"); 17 Thread t3=new Thread(tt); 18 t3.setName("窗口3"); 19 t.start(); 20 t2.start(); 21 t3.start(); 22 } 23 }
TicketThread.class----会出现多线程问题
1 package Test; 2 //实现Runnable接口启动线程 3 public class TicketThread implements Runnable{ 4 int tickets=100; 5 @Override 6 public void run() { 7 // TODO Auto-generated method stub 8 while(true){ 9 if(tickets>0){ 10 /*当有进程睡眠时会出现错误 11 * 当t来的时候有票进入if在里面睡眠,此时t2进来,t1还在睡眠因此仍有票,t2进入,同理t3也可进入 12 * 当t t2 t3出来后,票就开始自减就会出现问题。 13 */ 14 15 try { 16 //如果线程处于wait,sleep,join三个方法时候,则会抛出InterruptedException 17 Thread.sleep(100); 18 } catch (InterruptedException e) { 19 // TODO Auto-generated catch block 20 e.printStackTrace(); 21 } 22 23 //Thread是类名,类名+方法名直接调用方法,该方法必须是静态(static)方法 24 System.out.println(Thread.currentThread().getName()+":"+tickets--); 25 } 26 } 27 } 28 29 }
解决问题代码:
1 package Test; 2 //实现Runnable接口启动线程 3 public class TicketThread implements Runnable{ 4 int tickets=100; 5 Object obj=new Object(); 6 @Override 7 public void run() { 8 // TODO Auto-generated method stub 9 while(true){ 10 if(tickets>0){ 11 //同步代码块 obj为要锁的对象 12 synchronized (obj) { 13 try { 14 //如果线程处于wait,sleep,join三个方法时候,则会抛出InterruptedException 15 Thread.sleep(100); 16 } catch (InterruptedException e) { 17 // TODO Auto-generated catch block 18 e.printStackTrace(); 19 } 20 21 //Thread是类名,类名+方法名直接调用方法,该方法必须是静态(static)方法 22 System.out.println(Thread.currentThread().getName()+":"+tickets--); 23 } 24 25 26 } 27 } 28 } 29 30 }
对上面是代码的改善
1 package Test; 2 //实现Runnable接口启动线程 3 public class TicketThread implements Runnable{ 4 int tickets=100; 5 Object obj=new Object(); 6 @Override 7 public void run() { 8 // TODO Auto-generated method stub 9 while(true){ 10 method(); 11 } 12 } 13 14 //用synchronized修饰后该方法就会安全的方法,该方法是非静态方法因此默认同步锁对象为this 15 //若为静态方法时同步锁对象为当前类的字节码对象 16 private synchronized void method(){ 17 if(tickets>0){ 18 //同步代码块 obj为要锁的对象,但会造成运行效率低 19 try { 20 //如果线程处于wait,sleep,join三个方法时候,则会抛出InterruptedException 21 Thread.sleep(100); 22 } catch (InterruptedException e) { 23 // TODO Auto-generated catch block 24 e.printStackTrace(); 25 } 26 27 //Thread是类名,类名+方法名直接调用方法,该方法必须是静态(static)方法 28 System.out.println(Thread.currentThread().getName()+":"+tickets--); 29 } 30 } 31 32 }