java学习随手笔记(更新)
注: 该笔记中的知识点不具备连续性,这是我在学习Java中随手记下的东西,该笔记不是事无巨细的将所有的知识点一一记录,只是记录了我在听课过程中自我感觉需要记录的知识点。故此笔记不具备参考价值,如果您看到了这篇笔记,请将此略过。
向上转型是为了参数类型的统一
向下转型是为了调用子类中的特殊方法
工厂模式,耦合,
代理设计模式
包和访问控制权限
- import语句只能出现在package语句之下,class定义的语句之上。
- 但是,在idea里编辑时却没有这些问题,不晓得是什么原因。
有时设置set classpath不起作用,可以看一下cmd的表头是不是有系统无法在消息文件中为 Application 找到消息号为 0x2350 的消息文本。
如果有这个的话,应该在win+r里面直接控制cmd,这样问题才会解决
jar的一些命令
用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ...
选项:
-c 创建新档案
-t 列出档案目录
-x 从档案中提取指定的 (或所有) 文件
-u 更新现有档案
-v 在标准输出中生成详细输出
-f 指定档案文件名
-m 包含指定清单文件中的清单信息
-n 创建新档案后执行 Pack200 规范化
-e 为捆绑到可执行 jar 文件的独立应用程序
指定应用程序入口点
-0 仅存储; 不使用任何 ZIP 压缩
-P 保留文件名中的前导 '/' (绝对路径) 和 ".." (父目录) 组件
-M 不创建条目的清单文件
-i 为指定的 jar 文件生成索引信息
-C 更改为指定的目录并包含以下文件
如果任何文件为目录, 则对其进行递归处理。
清单文件名, 档案文件名和入口点名称的指定顺序
与 'm', 'f' 和 'e' 标记的指定顺序相同。
示例 1: 将两个类文件归档到一个名为 classes.jar 的档案中:
jar cvf classes.jar Foo.class Bar.class
示例 2: 使用现有的清单文件 'mymanifest' 并
将 foo/ 目录中的所有文件归档到 'classes.jar' 中:
jar cvfm classes.jar mymanifest -C foo/ .
比如说我要把包cn整成一个jar文件,我可以这样写
jar -cvf my.jar cn
这样就会生成一个jar文件。
比如我要看my.jar
的内容,我应该
jar -tvf my.jar
会出现像下面这样的目录结构
0 Fri Jan 31 16:34:48 CST 2020 META-INF/
69 Fri Jan 31 16:34:48 CST 2020 META-INF/MANIFEST.MF
0 Fri Jan 31 16:34:20 CST 2020 cn/
0 Fri Jan 31 16:34:20 CST 2020 cn/suyuesheng/
0 Fri Jan 31 16:34:20 CST 2020 cn/suyuesheng/demo/
406 Fri Jan 31 16:34:20 CST 2020 cn/suyuesheng/demo/Demo.class
要解压my.jar
就用jar -xf my.jar
注意,使用jar文件前必须设置CLASSPATH
- java的访问控制权限
- java的访问控制权限的表格
序号 | 范围 | private | default | protexted | public |
---|---|---|---|---|---|
1 | 同一类 | √ | √ | √ | √ |
2 | 同一包中的类 | √ | √ | √ | |
3 | 不同包中的子类 | √ | √ | ||
4 | 其他包中的类 | √ |
命名规范
一、命名规范
1、项目名全部小写,就是如果项目名是多个英语单词组成的,每个单词都要全部小写。
如:doubanssm。
2、包名全部小写。
3、类名首字母大写,也就是帕斯卡命名法,首字母大写,如果类名是多个单词拼成的,每个单词的首字母都要大写。
4、变量名、方法名首字母小写,也就是驼峰命名法,如果名称有多个单词组成,每个单词的首字母都要大写。
如:public int testJava(){}
5、常量名全部大写
如:public static final int ANIMAL_NUMBER=15;
二、命名规则
1、名称只能由字母、数字、下划线、$符号组成
2、不能以数字开头
3、名称不能使用JAVA中的关键字。
4、坚决不允许出现中文及拼音命名。
异常的处理流程
package cn.suyuesheng.errordemo;
//error 的标准用法
class MyMath{
public int div(int i,int j) throws Exception{//异常交给调用处
System.out.println("开始计算>>>>>>>>>>>>>>");
int temp=0;
try{
temp=i/j;
}catch (Exception e){//捕捉异常
throw e;//抛出异常,异常到了方法这里,随即到了方法调用出
}finally {
System.out.println("计算结束>>>>>>>>>>>>>>>>");
}
return temp;
}
}
//自定义异常
class MyException extends Exception{
public MyException(String msg){
super(msg);
}
}
public class ErrorLaw001 {
public static void main(String[] args) {
try{
System.out.println(new MyMath().div(12,3));
}catch (Exception e){
e.printStackTrace();
}
//
System.out.println(">-----------------------");
//检测自定义
try{
throw new MyException("haha");
}catch (MyException e){
e.printStackTrace();
System.out.println(e);
}
}
}
选择工作区,eciplse中所有的项目都是以工作区为主的,一个工作区中包含多个项目。
eclipse的所有配置都是以工作区为主的。每一个工作区的配置都是独立的。如果发现某一个工作区坏了(或者说你的工作区被整的乱七八糟了),重开一个工作区,一切都会好的
JDT的使用(重点)
jdk1.5新特性
package cn.suyuesheng.new01;
//java1.5 新特性
public class HelloDemo {
public static void main(String[] args) {
System.out.println(add(new int[] {1,2,3,354,54524,3}));
System.out.println(">================");
System.out.println(addone(1,2,3,4345,45,232453,2435,42534));//这样就能直接输入整形数据
System.out.println(addForEach(1,2,3,4,5,6,7,8,9,10));
}
/**
* 实现多个数据类型的累加操作
*
* @param data 使用数组完成接收
* @return 多个整形数据累加的结果
*/
public static int add(int data[]) {
int sum = 0;
for(int i=0;i<data.length;i++) {
sum+=data[i];
}
return sum;
}
/**
* 实现多个数据类型的累加操作,利用java1.5新特性
* @param arg
* @return
*/
public static int addone(int... arg) {
int sum=0;
for(int i=0;i<arg.length;i++) {
//参数定义的形式变了,但是参数的访问没有改变
sum+=arg[i];
}
return sum;
}
/**
* java1.5新特性 , foreach使数组的输出更为方便
* @param arg
* @return
*/
public static int addForEach(int...arg) {
int sum=0;
for(int x : arg) {
sum+=x;
}
return sum;
}
}
泛型
package cn.suyuesheng.fanxing;
//泛型的目的是解决向下转型的安全隐患
class Point<T> {// T是自定义的泛型标识
private T x;// 此变量的类型由外部确定
private T y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
public String toString() {
return "Point [x=" + x + ", y=" + y + "]";
}
}
public class FanXingDemoOne {
/**
*
* @param args
*/
public static void main(String[] args) {
Point<Integer> x = new Point<Integer>();// T类型自动变为Integer
x.setX(30);// 这时用到了自动封装
x.setY(20);// 这时用到了自动封装
System.out.println("(" + x.getX().intValue() + "," + x.getY().intValue() + ")");
Point<String> pp = new Point<String>();
pp.setX("东经10");
pp.setY("北纬25");
System.out.println(pp.toString());
// ありがとう
Point<Integer> cp = new Point<>();// JDK1.7之后可以这样设置
Point cf = new Point();// 这样默认设置类型为Object
cf.setX(14);
cf.setX(49);
System.out.println((Integer) cf.getX());
System.out.println(">++++++++++++++");
cp.setX(12);
cp.setY(16);
System.out.println(cp.toString());
}
}
一个类中多个泛型的情况👇
package cn.suyuesheng.fanxing;
public class FanXingDemoTwo<T, V> {// 指定多个泛型类型
private T age;
private V name;
// 泛型里面的构造方法
public FanXingDemoTwo() {
this.setAge((T) new Integer(12));
this.setName((V) "Amy");
}
public FanXingDemoTwo(T age, V name) {
super();
this.age = age;
this.name = name;
}
public T getAge() {
return age;
}
public void setAge(T age) {
this.age = age;
}
public V getName() {
return name;
}
public void setName(V name) {
this.name = name;
}
public String toString() {
return "FanXingDemoTwo [age=" + age + ", name=" + name + "]";
}
}
package cn.suyuesheng.fanxing;
public class FanXingDemoTwoTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
FanXingDemoTwo<Integer, String> cc = new FanXingDemoTwo<Integer, String>();
cc.setAge(12);
cc.setName("hah");
System.out.println(cc.toString());
System.out.println(">=================");
FanXingDemoTwo<Integer, String> bb = new FanXingDemoTwo<Integer, String>(20, "JJK");
System.out.println(bb.toString());
System.out.println(new FanXingDemoTwo<Integer, String>(40, "lili"));
System.out.println(cc);
System.out.println(">================");
fun(cc);
fun(new FanXingDemoTwo<Number, String>(120, "kkl"));
}
// 泛型的上限和下限
/* 泛型的上限和下限
* extends 定义上限
* super 定义下限
* ?表示全部类型(任意类型)
* */
public static void fun(FanXingDemoTwo<? extends Number, ? super String> temp) {
System.out.println(temp.getName());
System.out.println(temp);
}
public static void hun(FanXingDemoTwo temp) {
temp.setAge("qqq");//这是错误的
//错误的原因是:实例化对象设定的age的数据类型是Int。hun方法里却改数据类型为String。
}
}
泛型的接口👇
package cn.suyuesheng.fanxing;
//泛型接口
interface Imessage<T>{
void print(T t);
}
class Message<T> implements Imessage<T>{//这种定义方法把泛型类型也给继承了了
public void print(T t) {
System.out.println(t);
}
}
class Lmessage implements Imessage<Integer>{//这种方式在继承的同时注明了接口泛型的类型
public void print(Integer t) {//这里参数类型必须是Integer
System.out.println(t);
}
}
public class FanXingInterface {
public static void main(String[] args) {
Imessage<String> cc = new Message<String>();
cc.print("hello");
Imessage<Integer> bb = new Lmessage();
bb.print(12);
}
}
枚举
枚举可以限制一个类对象产生的范围
package cn.suyuesheng.meijv;
//枚举
//枚举实现接口
interface IColor{
public abstract void jj();
}
enum Color implements IColor{
RED("red"){
public void fun() {
System.out.println("红色");//每一个枚举对象都要覆写抽象方法
}
public void jj() {//每一个枚举对象都要覆写实现的接口的抽象方法
System.out.println("枚举能不用就不用");
}
},GREEN("green"){
public void fun() {
System.out.println("绿色");
}
public void jj() {
System.out.println("每一个枚举对象都要覆写实现的接口的抽象方法");
}
},BLUE("blue"){
public void fun() {
System.out.println("蓝色");
}
public void jj() {
System.out.println("每一个枚举对象都要覆写实现的接口的抽象方法");
}
};
//枚举中为对象的属性赋值
private Color(String name){//构造方法必须private
System.out.println("001");//会被执行三遍
this.setName(name);
}
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//枚举中的抽象方法
public abstract void fun();
}
public class MeiJvDemoOne {
public static void main(String[] args) {
Color c = Color.BLUE;
System.out.println(c);
System.out.println(">==================");
for (Color c1 : Color.values()) {
System.out.println(c1);
System.out.println(c1.ordinal());// 返回编号
System.out.println(c1.name());// 返回数据
System.out.println(c1.getName());
}
c.setName("hh");
System.out.println(c.getName());
Color.RED.fun();
System.out.println(">++++++++++++++");
for(Color b:Color.values()) {
b.fun();
b.jj();
System.out.println(b.getName());
System.out.println(b.name());
}
}
}
Annotation
//@Override 保证覆写的正确性
//@Override只能在方法上应用。在类和属性上是不能被用的。
//@Deprecated 声明不建议的或过期的类或方法
//Annotation
//@Override 保证覆写的正确性
//@SuppressWarnings 压制警告
package cn.suyuesheng.annotation;
//@Override 保证覆写的正确性
//@Override只能在方法上应用。在类和属性上是不能被用的。
//@Deprecated 声明不建议的或过期的类或方法
//Annotation
//@Override 保证覆写的正确性
//@SuppressWarnings 压制警告
class Book{
@Override
public String toString() {//这时,toString方法如果写成tostring的话,会在编译时就出错
return "hello";
}//@Override只能在方法上应用。在类和属性上是不能被用的。
//@Deprecated 声明不建议的或过期的类或方法
@Deprecated
public void fun(String t) {
System.out.println(t);
}
public void fun(int i,String t) {
System.out.println(i+t);
}
}
//@SuppressWarnings 压制警告
class Term<T>{
private T age;
public void setAge(T age) {
this.age = age;
}
public T getAge() {
return age;
}
}
//@Deprecated可以声明类
@Deprecated
class Person{
public void add() {
System.out.println("过期");
}
}
public class AnnotationDemoOne {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
System.out.println(new Book());//hello
Book b =new Book();
b.fun("hello");//这就是不建议的
@SuppressWarnings({ "unused", "rawtypes" })
Term t = new Term();//这样就没有警告了
t.setAge(12);
System.out.println(t.getAge());
}
}
jdk1.8新特性
- 接口可以定义普通方法,通过default和static
- jdk 1.8新特性之Lambda,意义是简化匿名内部类的代码
package cn.suyuesheng.xintexing;
//jdk 1.8 新特性
//接口可以定义普通方法,通过default和static
interface IUsb{
void message();
default void fun() {
System.out.println("default定义接口普通方法");
}
static void print() {
System.out.println("static 定义静态方法");
}
}
class Flash implements IUsb{
@Override
public void message() {
// TODO Auto-generated method stub
System.out.println("覆写");
}
}
//jdk 1.8新特性之Lambda,意义是简化匿名内部类的代码
interface Ik{
void ko();
// void add(int i,int j);
}
interface Ib{
void add(int i,int j);
}
public class XinTeXingDemo {
public static void main(String[] args) {
IUsb a = new Flash();
a.fun();
IUsb.print();
a.message();
/*
* default定义接口普通方法
static 定义静态方法
覆写*/
funn(()->System.out.println("hello world"));
ll((cv,b)->System.out.println(cv+b));
}
public static void funn(Ik ik) {
ik.ko();
}
public static void ll(Ib ib) {
ib.add(10, 20);
}
}
- jdk 1.8 方法引用
package cn.suyuesheng.xintexing;
//jdk 1.8 方法引用
/**
*
* @author 苏月晟
*
* @param <P> 参数类型
* @return <R> 返回值类型
*/
@FunctionalInterface // 此注解说明是函数式接口,只能定义一个方法
interface IMessage<P, R> {
public R fun(P p);// 静态方法引用
}
/**
*
* @author 苏月晟
*
* @return <R>
*/
@FunctionalInterface // 此注解说明是函数式接口,只能定义一个方法
interface IGod<R> {
public R up();// 普通方法引用
}
/**
* 特定类方法引用
* @author 苏月晟
*
* @param <P>
* @return <R>
*/
@FunctionalInterface
interface It<P,R>{
public R eq(P p1,P p2);//特定类方法引用
}
/**
* 构造方法引用
* @author 苏月晟
*
* @return <R>
*/
@FunctionalInterface //确保函数式接口,只能定义一个方法
interface IG<R>{
public R IG(int g2,String g1);//构造方法引用
}
class G{
private int age;
private String name;
public G(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "G [age=" + age + ", name=" + name + "]";
}
}
public class XinTeXingDemoTwo {
public static void main(String[] args) {
// 引用静态方法
// 类名称 :: 静态方法名称
// 将String.valueOf()的方法变为了IMessage接口里面的fun方法,也就是说msg里面的fun方法被覆写
// 覆写内容是String.valueOf()的内容
// 注意,Integer是String.valueOf()的参数类型
// String是String.valueOf()的返回值类型
// String.valueOf()是静态方法
IMessage<Integer, String> msg = String::valueOf;
System.out.println(msg.fun(12));// 12
System.out.println(msg.fun(12) instanceof String);// true
System.out.println(Integer.parseInt(msg.fun(10000).replaceAll("0", "9")));
int cc = Integer.parseInt(msg.fun(10000).replaceAll("0", "9"));
System.out.println(new Integer(cc) instanceof Integer);// true
int df = 7;
// 普通方法引用
// 实例化对象 :: 普通方法名称
IGod<String> igo = "hello"::toUpperCase;// 相当于igo的up方法是hello的toUpperCase方法
System.out.println(igo.up());// HELLO
System.out.println(igo.up() instanceof String);// true
It<String,Boolean> it = String :: equalsIgnoreCase;
System.out.println(it.eq("hello","kkk"));//引用的方法使用起来是,"hello".equalsIgnoreCase("kkk")
//构造方法引用
IG<G> gg = G::new;
System.out.println(gg.IG(12, "hello").toString());//G [age=12, name=hello]
}
}
- 内建函数式接口
java.util.function
中的类
package cn.suyuesheng.xintexing;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
//内建函数式接口,因为内建函数式接口的存在,我们很少直接定义函数式接口
/*函数式接口的种类
* 静态 类::方法名称
* 普通方法 实例化对象::方法名称
* 特定类方法 类::方法名称
* 构造方法 类::new
* */
/*内建式函数接口的种类:
* Function apply 有返回值和参数
* Consumer accept 有参数,没有返回值
* Supplier get 有返回值,没有参数
* Predicat test 有参数,返回值是Boolean
* */
public class NeiJian {
public static void main(String[] args) {
Function<String, Boolean> ff = "ll"::equalsIgnoreCase;
System.out.println(ff.apply("LL"));
Consumer<String> cc = System.out::print;
cc.accept("hello world");
System.out.println("\n");
Supplier<String> ss = "ll"::toUpperCase;
System.out.println(ss.get());
Predicate<String> pp = "lllhello"::contains;
System.out.println(pp.test("a"));
}
}
线程
一个java程序至少有两个线程,一个是main,一个是垃圾收集线程。
线程的实现有三种方法
第一种,👇 Thread。要使用Thread,必须要继承他,并实现run()方法。run()方法是线程的主体。要启动多线程,就必须要调用从Thread类中的start()方法
线程运行的过程中,交错运行,抢占cpu
package cn.suyuesheng.xiancheng.thread;
//多线程
class MyThread extends Thread{
private String name;
public MyThread(String name) {
this.name=name;
}
public void run() {//run()是线程的主体
for(int i=0;i<100;i++) {
System.out.println(this.name+"\t"+i);
}
}
}
public class ThreadDemoOne {
public static void main(String[] args) {
MyThread a1 = new MyThread("001");
MyThread a2 = new MyThread("002");
MyThread a3 = new MyThread("003");
a1.start();//启动多线程
a2.start();//交错运行,抢占cpu
a3.start();
}
}
第二种,实现Runnable接口。实现Runnable可以避免单继承局限,并且能够共享数据资源。一般情况下,选择Runnable
package cn.suyuesheng.xiancheng.runnable;
//thread 是runnable的子类,使用runnable接口可以避免单继承局限,还能方便的实现数据共享
class Mthread implements Runnable{
private int ticket =5;
public void run() {
for(int x:new int[100]) {
if(ticket>0) {
System.out.println(ticket--);
}
}
}
}
public class RunnableDemo {
public static void main(String[] args) {
Mthread mm = new Mthread();
new Thread(mm).start();
}
}
Runnable和Thread 的关系?
Runnable是接口,Thread是类。且Thread是Runnable接口的子类。使用这两种方式都要覆写run()方法。run()方法为线程的主方法。
Callable。👇
package cn.suyuesheng.xiancheng.callable;
//Callable 实现的子类里面call()方法可以有返回值
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
class MThread implements Callable<String>{
public int ticket=10;
public String call() throws Exception{
for(int x:new int[100]) {
if(ticket>0) {
System.out.println(ticket--);
}
}
return "票已经卖光";
}
}
public class CallableDemo {
public static void main(String[] args) throws Exception{
MThread mm = new MThread();
FutureTask<String> mmm = new FutureTask<String>(mm);
new Thread(mmm).start();//启动线程
MThread bb = new MThread();
FutureTask<String> bbb = new FutureTask<String>(mm);
new Thread(bbb).start();//启动线程
System.out.println(mmm.get());//获得线程返回的结果
System.out.println(bbb.get());
}
}
线程的相关方法
Thread.currentThread() 获得当前线程对象,有点像this
获得名字。Thread.currentThread().getName()
设置名字 setName 或在Thread构造方法中实现
优先级 setPriority 获得优先级 getPriority
睡眠和等待要try。。。catch
name.👇
package cn.suyuesheng.xiancheng.fangfa;
class Mythread implements Runnable{
private int ticket=100;
public void run() {//线程方法
for(int i=0;i<100;i++) {
if(ticket>0) {
System.out.println(Thread.currentThread().getName()+"\t"+ticket--);
}
}
}
}
public class TestDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Mythread mm = new Mythread();
new Thread(mm).start();
new Thread(mm,"自定义命名A").start();
new Thread(mm,"自定义命名B").start();
new Thread(mm).start();
new Thread(mm).start();
mm.run();
}
}
睡眠和优先级.👇
package cn.suyuesheng.xiancheng.fangfa;
class Mth implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "\t" + i);//Thread.currentThread() 获得当前线程对象,有点像this
} catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
public class SleepDemo {
public static void main(String[] args) {
Mth mm = new Mth();
Thread bo = new Thread(mm,"hello");
bo.setPriority(Thread.MAX_PRIORITY);//设定优先级
bo.start();
new Thread(mm, "A").start();
new Thread(mm, "B").start();
new Thread(mm, "C").start();
//Thread.currentThread() 获得当前线程对象,有点像this
System.out.println(Thread.currentThread().getPriority());//获得main对像的优先级
}
}
同步 同步代码块 synchrenized(对象,一般是this){}
同步方法 public synchronized 返回值 方法名称(){}
同步,上锁,即使休眠,只要synchronized代码块没被运行完,就不会有其他的线程运行synchronized中的内容。 class Sale implements Runnable{ 同步。👇
package cn.suyuesheng.xiancheng.fangfa;
//同步
//同步,上锁,即使休眠,只要synchronized代码块没被运行完,就不会有其他的线程运行synchronized中的内容
class Sale implements Runnable{
private int foodBox = 100;
public void run() {
for(int i=0;i<35;i++) {
try {
Thread.sleep(100);
}catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
synchronized (this) {//同步,上锁,即使休眠,只要synchronized代码块没被运行完,就不会有其他的线程运行synchronized中的内容
if(foodBox>0) {
try {
Thread.sleep(100);
}catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"\t"+foodBox--);
}
}
}
}
}
//synchronized 方法
class SaleOther implements Runnable{
private int cup =20;
public void run(){
for(int i=0;i<20;i++) {
try {
Thread.sleep(10);
}catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
this.buy();
}
}
public synchronized void buy() {
if(cup>0) {
try {
Thread.sleep(100);
}catch (InterruptedException e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println("恭喜"+Thread.currentThread().getName()+"! "+"买到了最后\t"+cup--+" 个");
}
}
}
public class TongBu {
public static void main(String[] args) {
// TODO Auto-generated method stub
// Sale m = new Sale();
// new Thread(m,"A").start();
// new Thread(m,"B").start();
// new Thread(m,"C").start();
SaleOther bb = new SaleOther();
Thread co = new Thread(bb,"D1");
co.setPriority(Thread.MAX_PRIORITY);
co.start();
new Thread(bb,"A1").start();
new Thread(bb,"B1").start();
new Thread(bb,"C1").start();
System.out.println(">____________");
System.out.println(Thread.currentThread().getPriority());
}
}