杰普Core Java课程笔记2

——年金波老师上课笔记

Core Java课程笔记2    1

Java面向对象基础    1

面向对象的思想:    1

Java中类的属性和方法的访问控制    6

高级特性    6

Java集合、反射、内部类、异常    8

集合(collection    8

反射:reflection    11

内部类    13

异常(Exception)    15

GUI 图形编程    18

布局实例    19

菜单实例    20

简易时钟    21

多线程    23

java中如何实现线程:    23

普通线程和精灵Deamon线程    24

线程同步    24

 

Java面向对象基础

面向对象的思想:

封装、继承、多态

1.封装:隐藏对象的属性和方法 private

2.继承:对象重用 减少代码冗余 extends

单继承 将父类的属性和方法 继承到子类中

3.多态:同一个类域(存在继承关系的类)的不同对象在调用相同方法的时候表现不同

 

封装:修饰符 public protected private 修饰属性和方法

public :其他类可以任意访问 自己类可以访问

protected:自己访问 子父类之间 相同包下

无:自己访问 相同的包下

class Person{

String name;

}

private 只有自己能访问

 

 

private Person(){

 

}

public static Person newone(){

return new Person();

}

Person p=Person.newone();

单例模式:在整个虚拟机中只有一个类的实例

专门处理日期

java.util.Date 濒临灭绝

java.util.Calendar 不能new

//指向系统当前时间

Calendar cal=Calendar.getInstance()

//获取年份

cal.get(Calendar.YEAR);

//获取月份

cal.get(Calendar.MONTH);

 

extends 后只能有一个父类:

this 表示当前类的实例

this.属性

this.方法(参数)

this();调用构造函数

this(参数):

方法的重载和重写

重载:在一个类内有多个相同(名字上)的方法

参数类型不同。参数个数不同。参数的顺序不同。

 

返回值:返回值是否相同对重载不构成影响

Person{

public void print(){}

public void print(String message){}

public void print(int level){}

}

构造函数也可以重载:

 

 

重写:发生在子类 。重新定义父类中的方法。

方法签名要跟父类相同

方法签名:返回值+方法名+方法参数(个数,顺序,类型 都相同)

super:访问父类中的属性和方法

super.父类属性

super.父类方法(参数)

super()//父类的构造器

super(参数)//调用父类的重载构造器

ch05/Father.java

package ch05;

public class Father{

protected String name;

protected int age;

 

public Father(){}

public Father(String name, int age){

this.name=name;

this.age=age;

}

public void print(){

System.out.println("Name :"+this.name +"\tAge :"+this.age);

}

}

 

ch05/Son.java

package ch05;

import java.u

public class Son extends Father{

public String[]hobby;

public Son(){}

public Son(String name, int age,String hobby []){

super(name,age);

//this.name=name;

//this.age=age;

this.hobby=hobby;

}

public void print(){

super.print();

System.out.println("Hobby:"+this.hobby);

}

 

public static void main(String args[]){

Son son=new Son("briup",1,new String []{"reading","gaming"});

son.print();

}

}

 

方法的参数传递

1.值传递:对于基本的参数类型 值拷贝(把外围的值拷贝到方法内供方法使用,对方法外的变量不构成影响)

mian(){

int a=10;

change(a);

System.out.println(a);

}

static void change(int a){

a=100;

System.out.println(a);

}

先打印出100

后打印出10

2.引用传递:地址值

Person p=new Person("test",18);

change(p);

System.out.println(p.getName());

}

static void change(Person p){

p.setName("briup")

System.out.println(p.getName());

}

 

都打印出briup

 

类的初始化:

静态初始化代码段: static {}

实例初始化代码段: {}

构造方法:

ch05/InitTest.java

package ch05;

public class InitTest{

static {

//jvm装载类的时候调用,无论创建多少个对象,都只会被调用一个。通常用来初始化静态成员变量

System.out.println("Static block is invoked!");

}

 

{

//创建实例之前进行调用,先与构造器

System.out.println("Instance block is invoked!");

}

 

public InitTest(){

System.out.println("Constructor method is invoked!");

}

public static void main(String args[]){

new InitTest();

System.out.println("--------");

new InitTest();

}

}

 

接口:interface 来声明。只允许定义常量 public static final String str="abc")和 空方法(抽象方法,没有实现)

public interface Test {

public void test(String test);

}

接口的作用:用来描述规范,被其他的接口或者类 实现或者继承

具体的类 实现(implements 接口(一个或者多个,多个之间用""分割),必须实现接口内的所有方法

接口 继承(extends) 接口

接口不能被实例化。接口在一定程度上弥补类java的单继承

抽象类:如果一个类没有完全的实现接口中的所有的方法,必须把没有实现的方法声明为抽象方法。。(abstract

如果一个类中有一个抽象方法,那么该类必须被声明为抽象类(public abstract class

功能更普通类是一样,抽象类可以分担子类的一本分功能

 

方法 实例化 创建引用

实体类: 全部实现 可以

抽象类: 部分实现 不可以

接口: 全部不实现      不可以

 

Son son=new Son();

Father son=new Son();

Son s=(Son)son;如果没有就报错:ClassCastingException

因为 Son 继承 Father

Father -> Son

抽象类 -> 继承了抽象类的具体类

接口-> 实现接口的具体类

casting 类型转换,引用或者类类型

向上转换:不需要显示的类型转换

向下转换:要显示的强制类型转换

上:father

下:son

ch05/log.java

ch05/Baselog.java

ch05/SystemLogImoI.java

ch05/FilelogImo.java

ch05/LogTest.java

 

员工管理:

对于员工:crretravelud

DML insert

DDL drop

存放员工的数据结构-queue

 

EmppoyeeDate{ Employee [] emArray;

create();//增加员工

findint id);

update 更新

delete

}

 

Java中类的属性和方法的访问控制

  1. 类没有protectedprivate修饰符
  2. public 修饰的类,可以被其它包中的类访问
  3. 没有被public 修饰的类,不能被其它包中的类访问
  4. 同一包中,不能访问其它类的private 属性和方法
  5. 同一包中,可以访问其它类的默认 属性和方法
  6. 同一包中,可以访问其它类的protected 属性和方法
  7. 同一包中,可以访问其它类的public 属性和方法
  8. 同一包中,不能访问父类的private 属性和方法
  9. 同一包中,可以访问父类的默认 属性和方法
  10. 同一包中,可以访问父类的protected 属性和方法
  11. 同一包中,可以访问父类的public 属性和方法
  12. 不同包中,无法访问不同包的其它类的private 属性和方法
  13. 不同包中,无法访问不同包的其它类的默认 属性和方法
  14. 不同包中,无法访问不同包的其它类的protected 属性和方法
  15. 不同包中,可以访问不同包的其它类的public 属性和方法
  16. 不同包中,无法访问父类的private 属性和方法
  17. 不同包中,无法访问父类的默认 属性和方法
  18. 不同包中,无法访问父类的protected 属性和方法
  19. 不同包中,可以访问父类的public 属性和方法

可以看到,类中的默认的属性和方法为protected修饰的

 

高级特性

static

1.修饰属性:所有的类的实习共享同一个属性

2.修饰方法:类名.方法名(调用方法)

3.{};用来初始化类的static属性

规则:

static修饰的方法不能访问非static变量(成员变量)

static修饰的方法不能访问非static方法(成员方法)

例:监控程序

监控程序:监控类实例的个数

ch06/InstanceCounter.java

package ch06;

public class InstanceCounter{

public static int count;

//初始化

static{

count=0;

}

 

{

count++;

}

 

public InstanceCounter(){

System.out.println("A new instance is created!");

}

public static void main(String args[]){

Object o1=new InstanceCounter();

Object o2=new InstanceCounter();

o1=null;o2=null;

System.gc();

System.out.println("Instance count:"+count);

}

//重写父类方法。范围不能变小. finalize 回收对象/实例占用的资源

public void finalize(){

count--;

System.out.println("Instance will be revoled by GC!");

}

}

Final修饰符

final:提高程序的健壮性

1.修饰类 该类不能被继承 java.long.String 不能有子类)

2.修饰属性,改属性为常量 (程序运行期间值不能被改变的叫常量) 常量的赋值:在第一次被赋值之后,永远不能改变。常量的命名:全部大写 用下划线分隔 MAX_SIZE

3.修饰方法 该方法不能被重写

StringBuffer

StringBuffer 提高效率

缓存:提高效率

String : 做频繁的字符串连接操作,非常浪费系统空间

String str="abc";

str+="xyz";

str="abcxyz";

 

StringBuffer str=new StringBuffer("abc");

str.append("xyz");

str.toString()->StringBuffer->String;

StringBuilderStringBuffer

StringBuilderStringBuffer 使用方式完全相同

StringBuffer 线程安全

对象的比较

对象的比较:== 对于引用来说比较的地址值 。对于基本类型比较的数值

比较对象的内容:equals方法

Person p1 = new Person("briup",13);

Person p2 = new Person("briup",13);

p1.equals(p2) -> true :内容相同 false ->内容不同

equals的来源:java.long.object ,默认实现相当与== 重写该方法完成自定义的内容比较

public boolean equals(Object obj){

if(obj=null)

return false;

if(this=obj)

return true;

if(this.getClass()!=obj.getClass())

return false;

Person p1=(Person)obj;

return this.getName().equals(p1)&&this.getAge()==p1.getAge();

}

代码覆盖率:测试用例是否可以覆盖(执行)所有代码

Java集合、反射、内部类、异常

集合(collection

管理若干个对象

List:管理重复对象

1.Aarraylist:基于数组的实现

2.LinkedList:基于链表的实现

Set:管理不可重复的对象

1.HashSet:检索快

2.TreeSet:排序(自定义规则)

Map:做检索功能。键值对。key->value

 

例:HashMap:

ch06/ListTest.java

package ch06;

import java.util.*;

public class ListTest{

public static void main(String args[]){

//创建ArrayList

List aList=new ArrayList();

//add 添加

aList.add(new Integer(100));

aList.add(new Boolean(false));

aList.add(new Person("briup",false,1));

aList.add(new Person("briup-999",true,2));

out(aList);

outByIndex(aList);

}

/*

遍历list

*/

public static void out(List list){

Iterator it = list.iterator();

while(it.hasNext()){

Object obj=it.next();

System.out.println(obj);

}

}

public static void outByIndex(List list){

System.out.println("---------------------------------------");

int length=list.size();

for(int i=0;i<length;i++){

Object obj=list.get(i);

System.out.println(obj);

}

}

 

}

 

对集合进行遍历

迭代器:

java.util.Iterator{

boolean hasNext();//判断是否存在下一个元素

Object nest();//取下一个元素

 

}

 

fot(int i=0;i<3;i++){

it.next();

}

Object obj=it.next();

println(obj);

 

List:放置可重复的对象

Set :放置不可重复的对象 有对象的equals方法(返回true)和hashCode方法(返回的int值相等)决定。

HashSet:

TreeSet

 

ch06/SetTest.java

package ch06;

import java.util.*;

public class SetTest{

public static void main(String args[]){

Set set=new HashSet();

Person p1=new Person("briup",false,1);

Person p2=new Person("briup--2",false,2);

Person p3=new Person("briup--3",false,3);

set.add(p1);

set.add(p2);

set.add(p3);

out(set);

}

public static void out(Set set){

Iterator it =set.iterator();

while(it.hasNext()){

Person p=(Person)it.next();

System.out.println(p);

}

}

}

 

hashCode来源于object对象

Object obj=new Object();

System.out.println(obj);

java.lang.Object@adfasdf123(hashCode方法返回);

 

TreeSet:在向集合中添加元素的同时进行排序。对放入treeSet中的对象实现comparable接口并实现compareTo方法

Person 排序:

p1.compareTo(p2):p1>p2 return 1;p1=p2 return 0; p1<p2 return -1;

先排name String类型按字母表的数序

如果相等

再按age

 

Map->HashMap 键值对 key-value

key value 可以是任何的object

一般情况下使用String作为key,valueObject

"briup-1" à new Person"briup-1"true1);

 

ch06/MapTest.java

package ch06;

import java.util.*;

public class MapTest{

public static void main(String args[]){

Map map=new HashMap();

fill(map);//填充

out1(map);//遍历1

out2(map);//遍历2

}

public static void fill(Map map){

for(int i=0;i<1000;i++){

Person p = new Person("briup-"+i,true,1);

//第一个参数key值,第二个参数value

map.put(p.getName(),p);//添加

}

}

public static void out1(Map map){

Set keySet=map.keySet();

Iterator it=keySet.iterator();

while(it.hasNext()){

String key=(String)it.next();

Person value=(Person)map.get(key);

System.out.println("key:"+key+"\t->"+"\tvalue:"+value);

}

}

public static void out2(Map map){

Set set=map.entrySet();

Iterator it=set.iterator();

while(it.hasNext()){

Map.Entry entry=(Map.Entry)it.next();

String key=(String)entry.getKey();

Person value=(Person)entry.getValue();

System.out.println("key:"+key+"\t->"+"\tvalue:"+value);

}

}

}

 

存:put (key,value)

取:get(key)返回value

map遍历的两种方式:

1.获取map中所有的key map.keySet();

2.Map.Entry封装了key value

 

反射:reflection

使用反射来处理class文件

java.lang.reflect.*;

Class{//描述一个类

Field//描述类中的属性

Method//描述类中的方法

Constructor//描述类的构造函数

}

反射的作用:

1、修改虚拟机中对象的属性(非常规)

可以直接修改private属性

person.setName();

2、条用对象的方法(非常规)

person.toString();

3、不通过new来创建类的对象的实例

new Person();

 

获取类的class实例:

1Class clz=Class.forName("ch06.Person");//需要处理异常

2、类的引用.getClass();

Class clz=p1.getClass();

3、类名.class

Class clz=Person.class;

4.类名.getSuperClass()

Class clazz=p1.getSuperclass();

5.primitive wraper classes.TYPE语法

    用于得到基本类类型:class clazz=Integer.TYPE;

 

ch06/ReflectTest.java

package ch06;

import java.lang.reflect.*;

public class ReflectTest{

public static void main(String args[]) throws Exception{

if(args.length!=1){

System.out.println("Please run the prog with class name");

System.exit(0);

}

Class clz=Class.forName(args[0]);

Method[] method=clz.getDeclaredMethods();

for(int i=0;i<method.length;i++){

System.out.println(method[i].getName());

}

}

}

 

ch06/ReflectAd.java//修改属性值

package ch06;

import java.lang.reflect.*;

public class ReflectAd{

public static void main(String args[]) throws Exception{

Person p1=new Person("briuo-999",true,10);

System.out.println("Before modify:"+p1);

Class clz=Person.class;

Field[] field =clz.getDeclaredFields();

for(int i=0;i<field.length;i++){

if(field[i].getName().equals("name")){

//调用setAccessible方法后可修改属性值

field[i].setAccessible(true);

//具体的修改方法:第一个参数说明要修改哪一个实例,第二个参数是修改后的值

field[i].set(p1,"briuo-888");

 

}

}

System.out.println("After modify:"+p1);

}

}

 

ch06///用对象的方法//

Method [] method=clz.getDeclaredMethods();

for (int i=0;i<method.length;i++){

if(method[i].getName().equals("toString")){

String resule=(String)method[i].invoke(p1);

System.out.println("@@@@@@@@@@@@2result");

}

if(method[i].getName().equals("setAge")){

method[i].invoke(p1,100);

System.out.println("!!!!!"+p1);

}

动态的创建类

不通过new来创建类的对象的实例:通过字符串形式命名,将类名迁移到配置文件中(通常是文本文件形式),根据横序的运行,动态的创建类得实例

 

Constructor constructor =clz.getConstructor(String.class, boolean.class, int.class);

Object obj=constructor.newInstance("briup-000",false,100);

System.out.println("Constructor a new instance without new :" +obj);

 

内部类

//解耦:数据跟程序解耦

//高内聚,低耦合

内部类:类里面的另外的类 共享外部类的资源;有效的避免命名冲突

成员内部类:

ch06.Outer_1.java

package ch06;

 

public class Outer_1{

public String str="abc";

public void show(){

System.out.println(str);

}

class Inner{

public String innerStr="ABC";

public void innerShow(){

System.out.println(innerStr);

System.out.println(str);

}

}

public static void main(String args[]){

Outer_1 outer=new Outer_1();

outer.show();

//实例化成员内部类

//创建成员内部类的实例必须依赖于外部类的实例

Outer_1.Inner inner=outer.new Inner();

inner.innerShow();

}

}

 

静态内部类:

不许要创建外部类的实例即可创建内部类实例。可以到达一定程度的封装

ch06/Outer_2.java

 

package ch06;

public class Outer_2{

public static String str="abc";

public static class Inner{

public String innerStr="xyz";

public void showPara(){

System.out.println(innerStr);

}

}

 

public static void main(String args[]){

//创建内部类的实例,不需要外围类的实例

Outer_2.Inner inner=new Outer_2.Inner();

inner.showPara();

//静态内部类只能访问外围类的静态属性和静态方法,因为静态内部类不持有外围类的实例

}

}

 

局部内部类:

类可以写在任意的地方

ch06/Outer_3.java

package ch06;

public class Outer_3{

public static void main(String args[]){

class Inner{

public String str="abc";

public void show(int number){

System.out.println(str);

System.out.println(number);

}

}

Inner inner =new Inner();

inner.show(100);

}

}

 

匿名内部类:

ch06.Outer_4.java

package ch06;

interface Test{

public void test(String message);

}

public class Outer_4{

public static void main(String args[]){

new Test(){

public void test(String message){

System.out.println(message);

}

}.test("briup");

//创建一个实现Test接口的匿名内部类。并同时调用test方法

}

}

 

异常(Exception)

1.异常

异常:程序无法正常运行 程序当中的错误

异常处理的机制:遇到异常代码,jvm寻找异常处理,如果找不到异常处理语句,则将该异常抛出至上层代码,如此反复,直至抛给虚拟机,终止程序运行

异常的分为两类:checked 异常(继承java.lang.Exception的异常(在代码中必须处理))unchecked异常(java.lang.RuntimeException(不许要在程序编译的时候处理)

checked:编译期检查 如果源代码中没有进行处理,则无法通过编译

unchecked:运行期检查 编译的不会检查

Class.forName()->ClassNotFound

对于异常的处理:

1.try{//一般来说出来checked异常

//+可能有问题的代码

}catch(异常的类型1{

//+处理异常的代码

}catch(异常的类型1{

//+处理异常的代码

}finally{

//+必须执行的代码段 通常用来回收资源

}

 

2.throw 异常类型

ch07/ExceptionTest.java

 

returnfinally(无论代码是否异常。都只返回finallyreturn)

ch07/ExceptionTest2.java

package ch07;

public class ExceptionTest2{

public static double divide(int a,int b){

/*if(b==0){

System.out.println("Can not / by zero");

return 0;

}*/

try{

return a/b;

}catch(ArithmeticException e){

System.out.println("Can not / by zero");

e.printStackTrace();

return 0;

}catch(Exception e1){

System.out.println("another Exception");

e1.printStackTrace();

return 0;

}finally{

return 100;

}

 

}

public static void main(String args[]){

System.out.println(divide(10,1));

System.out.println(divide(10,0));

System.out.println(divide(10,2));

}

}

 

3.自定义的异常:

一般都是unchecked;阐述系统中的业务逻辑错误

UersNotFoundException:找不到数据的用户

if(user==null)

throw new UserNotFoundException;

throw new NullPointerException;

实现:check异常

ch07/MyCheckedException.java

package ch07;

public class MyCheckedException extends Exception{

public MyCheckedException(){

super();

}

public MyCheckedException(String message){

super(message);

}

}

 

ch07/MyCheckedExceptionTest.java

package ch07;

public class MyCheckedExceptionTest {

public static void test(String para) {

if(para.equals("abc")){

throw new MyCheckedException("Parameter can not be abc");

}

System.out.println(para);

}

public static void main(String args[]){

try{

test("xyz");

test("abc");

test("string");

}catch(MyCheckedException e){

e.printStackTrace();

}

}

}

 

ch07/MyUnCheckedException.java

package ch07;

public class MyUncheckedException extends RuntimeException{

public MyUncheckedException(){

super();

}

public MyUncheckedException(String message){

super(message);

}

}

 

ch07/MyUncheckedExceptionTest.java

package ch07;

public class MyUncheckedExceptionTest {

public static void test(String para){

if(para.equals("abc")){

throw new MyUncheckedException("Wrong Parameter:");

}

}

public static void main(String args[]){

test("xyz");

test("abc");

test("string");

}

}

 

4.断言

断言:在程序运行过程中进行debug

偏向于测试

assert 布尔表达式(返回false的时候抛出AssertionError)

assert 布尔表达式:"断言信息"

开启断言:java-ea ch07/Test

当没开启断言的时候,对程序的效率没有任何影响

判断程序运行过程中变量的值是否符合预期

ch07/AssertTest.java

package ch07;

public class AssertTest{

public static void main(String args[]){

System.out.println("Before");

assert 1==1;

assert 1!=1:"wrong !!!";//类似于自定义异常的有参的函数构造

System.out.println("After");

 

 

}

}

判断程序运行的参数是否是"briup",如果不是则抛出异常

 

GUI 图形编程

容器:用来存放组件或者子容器

顶级容器:只能存放组件或者其它子容器(javax.swing.Jframe

子容器:可以被其他容器所包含 也可以包含其他组件或者容器(javax.swing.JPanel

组件:按钮。文本框。菜单 javax.swing.*;包下

布局:用来表示组件或者容器的相对位置

1.FlowLayout 流式布局 组件顺序拜访

2.BorderLayout 边框布局 5个部分:south north west east center

3.GridLayout 表格布局 以行和列的形式将组件组织在一起

布局实例

ch08/FlowLayoutTest.java

package ch08;

import javax.swing.*;

import java.awt.*;

public class FlowLayoutTest{

private JFrame frame;

private Container contentPane;

private JButton btn_1,btn_2,btn_3,btn_4,btn_5;

public FlowLayoutTest(){

frame=new JFrame("Flow Layout Test");

frame.setSize(400,300);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

initGUI();

}

public void initGUI(){

contentPane=frame.getContentPane();

contentPane.setLayout(new FlowLayout());

btn_1=new JButton("fisrt btn");

btn_2=new JButton("second btn");

btn_3=new JButton("third btn");

btn_4=new JButton("fourth btn");

btn_5=new JButton("fifth btn");

contentPane.add(btn_1);

contentPane.add(btn_2);

contentPane.add(btn_3);

contentPane.add(btn_4);

contentPane.add(btn_5);

contentPane.add(s);

}

public void go(){

frame.setVisible(true);

}

public static void main(String args[]){

new FlowLayoutTest().go();

}

}

 

JMenultem 菜单项 "复制" "粘帖"

JMenu 菜单 "编辑" "查看"

JMenuBar 菜单条

m_1.add(new JSeparator());    //添加滚动条

菜单实例

ch07\MenuTest.java

package ch07;

import javax.swing.*;

import java.awt.*;

 

public class MenuTest

{

private JFrame frame;

private Container contentPane;

private JMenuItem m_item_1,m_item_2;

private JMenu m_1,m_2;

private JMenuBar mb;

public MenuTest()

{

frame=new JFrame("Menu Test");

frame.setBounds(200,200,400,200);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

contentPane=frame.getContentPane();

initGUI();

}

 

public void initGUI()

{

contentPane.setLayout(new BorderLayout());

m_1=new JMenu("Edit");

m_2=new JMenu("About");

m_item_1=new JMenuItem("Ctrl c");

m_item_2=new JMenuItem("Ctrl v");

m_1.add(m_item_1);

m_1.add(new JSeparator());

m_1.add(new JMenuItem("test"));

m_2.add(m_item_2);

mb=new JMenuBar();

mb.add(m_1);

mb.add(m_2);

contentPane.add(mb,BorderLayout.NORTH);

}

public void go()

{

frame.setVisible(true);

}

public static void main(String[] args)

{

new MenuTest().go();

}

}

 

时间:EmotionEvent

事件源:Girl

事件处理范围:

interface EmotionListener{

happy(EmotionEvent e);

sad(EmotionEvent e);

}

观察者设计模式:

ch09/EmotionListener.java

ch09/EmotionEvent {

事件源 Object

时间模式 String

}

 

简易时钟

package ch07;

 

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;

 

public class ClockDemo implements ActionListener

{

private JFrame frame;

private JPanel clockPanel;

private Container contentPane;

 

public void actionPerformed(ActionEvent e)

{

}

 

public ClockDemo()

{

frame=new JFrame("ClockDemo");

contentPane=frame.getContentPane();

frame.setBounds(200,200,400,400);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

initGUI();

}

 

public void initGUI()

{

contentPane.setLayout(new BorderLayout());

clockPanel=new ClockPanel();

contentPane.add(clockPanel);

}

 

public void go()

{

frame.setVisible(true);

}

 

public static void main(String []args)

{

new ClockDemo().go();

}

}

 

class ClockPanel extends JPanel implements ActionListener

{

private Timer timer;

//private java.util.Random rand;

private int i=-15,j=-15,k=-15;

public ClockPanel()

{

//rand=new java.util.Random();

timer=new Timer(20,this);

timer.start();

}

 

public void actionPerformed(ActionEvent e)

{

updateUI(); //4הJPanel

}

 

public void paint(Graphics g)

{

int cx=200,cy=200; //ԲЄλփ

//int x1=rand.nextInt(400);

//int y1=rand.nextInt(400);

//int x2=rand.nextInt(400);

//int y2=rand.nextInt(400);

i++;

if(0==(i+15)%60)

{

j++;

if(0==(j+15)%12)

{

k++;

}

}

double r1=150,r2=120,r3=100; //

double alpha=Math.PI/30.0; //һΗ߶˹תŶȊ

 

g.clearRect(0,0,400,400);

//g.drawLine(x1,y1,x2,y2);

g.drawOval(50,50,300,300);

for(int n=0;n<60;n++)

{

double r0=r1-3.0;

if(0==n%5)

{

r0=r1-8.0;

}

g.drawLine((int)(cx+r0*Math.cos(n*alpha)),(int)(cy+r0*Math.sin(n*alpha)),(int)(cx+r1*Math.cos(n*alpha)),(int)(cy+r1*Math.sin(n*alpha)));

}

g.drawLine(cx,cy,(int)(cx+r1*Math.cos(i*alpha)),(int)(cy+r1*Math.sin(i*alpha)));

g.drawLine(cx,cy,(int)(cx+r2*Math.cos(j*alpha)),(int)(cy+r2*Math.sin(j*alpha)));

g.drawLine(cx,cy,(int)(cx+r3*Math.cos(k*alpha)),(int)(cy+r3*Math.sin(k*alpha)));

 

}

}

 

多线程

java优点:跨平台 多线程

进程:在os运行一个程序 用来完成一个独立完整的任务 至少要有一个线程(主线程)

线程:将一个完整的任务分解成若干的独立的小任务来完成 (本质)更多的抢占cpu的时间片,达到并怕执行的效果

计算机在同一时刻只能执行一条指令(单核)

线程由进程衍生出来。地址空间共享。data共享。code共享。是独立运行的分支(程序流)

java中如何实现线程:

1.继承Thread

2.实现Runnable接口 解决单继承

都要实现run(),线程所要做的事情

public void run(){

 

}

如果run方法调用结束,线程结束

启动线程:线程的引用.start();

eclipse:

ch10/ThreadByExtends.java

ch10/ThreadByImplements.java

debug:断点debug 一步一步执行代码

 

普通线程和精灵Deamon线程

Thread.setDeamon(boolean);//设置普通线程为Deamon线程

Deamon线程:在后台运行的线程。对于Deamon线程始终依赖(生命周期)与另外一个线程

普通线程不存在依赖关系

setDeamon()必须在start();之前调用

线程的优先级:如果优先级不同,那么线程运行的先后顺序可以不一样(取决于操作系统的调度程序)

Thread.setPriority(0-10);

java.lang.Thread

Thread.sleep();让线程暂时停止运行某一特定的时间

Thread t=Thread.currentThread();获取当前运行的线程的实例(静态方法)

停止线程:不建议使用stop。可以设置标志位,通过对标志位的读取来终止线程的运行

boolean flag=true;

if(!flag)

return;

线程同步

线程同步:多个线程操作同一个对象的时候

1.为了保证多个线程操作同一个对象的完整性,可以对需要同步的方法使用synchronized修饰

2.使用synchronized修饰的方法,在调用的时候必须先获得该对象的锁(一个对象只有一把锁),只有获得了锁之后,同步方法才能被调用,调用之后锁被自动的释放

3.修饰代码块

synchronized(对象的引用){

需要同步的代码

}

传入的对象的引用被synchronized加锁。降低加锁的粒度。

ch10/SynchronizedTest.java

思索:deadlock 当两个对象相互持有对方所需要的锁的时候,并且都得不到释放,这时候产生死锁。。。。。。

ch10/DeadLockTest.java :锁得不到释放

 

wait():释放对象的锁 java.lang.Object

对象的引用.wait();释放引用锁指向的对象的锁,使当前程序停止运行,等待其他线程调用notify()进行通知后方可运行

sleep()不会释放对象的锁

转载于:https://www.cnblogs.com/luowei010101/archive/2011/12/13/2285483.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值