线程

一、线程的创建

1、继承Thread类

步骤:1、先继承Thread类;2、重写Run()方法;3、调用start()方法开启线程。

2、实现Runable接口

步骤:1、先实现Runable()接口;2、实现Run()方法;3、Thread thread = new Thread(new MyThread());4、调用start()方法开启线程。
注:不要直接在程序中调用线程的run方法;

二、线程休眠

先获取当前线程,设置休眠时间:

Thread.currentThread().sleep(1000);

三、线程传参

1、构造方法传参

public class MyThread extends Thread{

    private int second;

    public MyThread(int sec){
        this.second = sec;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        for(int i = second;i >= 1;i--){
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        java.awt.Toolkit.getDefaultToolkit().beep();

    }

}

2、set方法传参

public void setSecond(int second) {
        this.second = second;
}

四、线程优先级

student1.setPriority(1);
注:System.exit(0);//程序停止

五、线程同步

    public synchronized void p(String name,int math,int chinese){
        System.out.println("姓名:"+name);
        System.out.println("   语文:"+chinese);
        System.out.println("   数学:"+math);
    }

六、StringBuffer和StringBuilder

1、StringBuffer sb;//线程安全 效率低
StringBuffer s = new StringBuffer();//初始化出一个为空的对象
StringBuffer s = new StringBuffer("abcdf");//初始化值为abcdf的对象
注:String与StringBuffer为不同的类型,不能直接强制转换
StringBuffer s = "abc";
StringBuffer s (StringBuffer)"abc";//这两种方式都是错误的
String s = "abc";
StringBuffer sb1 = new StringBuffer("123");
StringBuffer sb2 = new StringBuffer(s); //String转换为StringBuffer
String s1 = sb1.toString();//StringBuffer转换为String
2、StringBuilder su;//线程不安全 效率高
方法与StringBuffer一样

七、死锁

死锁原理:有两个资源a和b,两个用户1和2;线程开启时1获得a,又想获得b,但是2已获得b,又想获得a;这种情况下双方都在等待对方释放资源,故成死锁;但也有例外,若是1获得a后又获得b,此时b未被2获得,死锁便不成立。(线程调度有系统决定)

    public static void main(String[] args) {

        Resource res1 = new Resource();
        Resource res2 = new Resource();

        Use user1 = new Use("lin", res1, res2);
        Use user2 = new Use("liang", res2, res1);

        user1.start();
        user2.start();

    }
public class Use extends Thread{

    private String name;
    private Resource res1;
    private Resource res2;
//  private Resource res3;

    public Use(String name,Resource res1,Resource res2){

        this.name = name;
        this.res1 = res1;
        this.res2 = res2;

    }

    @Override
    public void run() {

        System.out.println("申请获得name");
        synchronized (res1) {
            System.out.println("已获得");
            System.out.println(res1.getName());
            System.out.println("申请获得age");
            synchronized (res2) {
                System.out.println("已获得");
                System.out.println(res1.getAge());
            }
            System.out.println("释放age");
        }
        System.out.println("释放name");

    }

}

synchronized关键字的使用:
1、synchronized关键字不能继承
父类中的方法有使用到synchronized,在子类中重写这个方法时,该方法默认情况下并不是同步的,而是要显示的在该方法中加上synchronized;但是在子类方法中调用父类的同步方法,虽然子类的方法不是同步的,但此时子类的方法也相当于同步。
2、在定义接口是不能使用synchronized关键字。
3、构造方法不能使用synchronized关键字,但可以使用synchronized块来进行同步。
4、synchronized可以自由放置,但不能放置在方法返回类型的后面,只能用来同步方法,不能用来同步变量。

你可能感兴趣的:(Java基础)