java多线程学习笔记(一)

java多线程学习笔记(一)

  1. 关于线程
public class chapter1 {
     //关于线程
    public static void main(String[] args) {
        //打印当前线程的名称
        System.out.println(Thread.currentThread().getName());

        /*
        * 输出结果为main 但是这个结果和main方法本身没有关系,仅仅是名字相同。
        *
        * 实现多线程的方式主要有2种,一种是继承Thread类,还有一种是实现Runnable接口。他们之间是多态的关系。
        * 但是由于java不支持多继承,支持多继承推荐使用实现Runnable接口的方式。
        * */

2.继承Thread类

public class chapter2_1 extends Thread{
    //继承Thread类
    @Override
    public void run(){
        super.run();
        System.out.println("2-1MyThread");
    }


public class chapter2_2 {
    public static void main(String[] args) {
        chapter2_1 mythread=new chapter2_1();
        mythread.start();
        System.out.println("2-2运行结束");
        /*
        注意:多次重复调用start方法会出现报java.lang.IllegalThreadStateException异常
        * 输出结果为:
        * 运行结束
        * MyThread
        * 可以看到2—1类中的run()方法执行较晚。
        * 表明多线程技术中的代码的运行结果和调用顺序是无关的。
        * 值得注意的是,在Thread的构造方法中有一条:Thread(Runnable target)
        * 而且Thread本身也实现了Runnable接口,所以new Thread()时可以直接传递Thread类对象。
        * 如此可以实现将一个线程中的run()方法交由其他线程调用。
        * */
    }
}

3.1线程数据的不共享情况

public class MyThread extends Thread{
//线程数据不共享
private int count=5;
public MyThread(String name){
    super();
    this.setName(name);
}
@Override
public void run(){
    super.run();
    while(count>0){
        count--;
        System.out.println("Threadname="+this.currentThread().getName()+"  count="+count);
    }
}
}



public class Run {


    public static void main(String[] args) {
        MyThread a=new MyThread("a");
        MyThread b=new MyThread("b");
        MyThread c=new MyThread("c");
        a.start();
        b.start();
        c.start();
        /*输出结果:
        Threadname=c  count=4
        Threadname=c  count=3
        Threadname=a  count=4
        Threadname=b  count=4
        Threadname=b  count=3
        Threadname=b  count=2
        Threadname=b  count=1
        Threadname=b  count=0
        Threadname=a  count=3
        Threadname=a  count=2
        Threadname=a  count=1
        Threadname=a  count=0
        Threadname=c  count=2
        Threadname=c  count=1
        Threadname=c  count=0
        */
    }

}

3.2线程数据共享(非线程安全)

public class MyThread extends Thread{
//线程数据不共享
  private int count=5;
@Override
  public void run(){
    super.run();

        count--;
        System.out.println("Threadname="+this.currentThread().getName()+"  count="+count);
}
}



public class Run {


    public static void main(String[] args) {
        MyThread  myThread=new MyThread();
        Thread a=new Thread(myThread,"a");
        Thread b=new Thread(myThread,"b");
        Thread c=new Thread(myThread,"c");
        Thread d=new Thread(myThread,"d");
        Thread e=new Thread(myThread,"e");
        a.start();
        b.start();
        c.start();
        d.start();
        e.start();
        /*输出结果:
       Threadname=a  count=4
       Threadname=c  count=2
       Threadname=b  count=2
       Threadname=e  count=1
       Threadname=d  count=0
       此时线程c和b同时对count访问出现了错误,2者的结果都是2.此时数据count是线程不安全的。
       出现这种情况的原因是因为在jvm中,count--包括了取数、计算、赋值到原变量三个过程,如果同步执行可能同时发生了
       取数等等操作导致结果出错。
       如果对MyThread类中重写的run方法加锁,就可以避免这种情况。
       synchronized可以在任意对象或者方法上加锁,这段加锁的代码称为临界区/互斥区。

       注意:在System.out.println();语句的括号内如果进行了比如System.out.println((i--))之类的操作,
       i--是在进入括号之前完成的,还是有非线程安全的可能性。

        */
    }

}

  • 关于Thread.start()与Thread.run()方法:
    start()方法通知线程规划器此线程准备就绪,等待调用线程对象中的run()方法,简单的来说是异步执行的。
    thread.run()方法是由main主线程调用run()方法,所以说是同步执行的。从如下的例子可以更好的理解这个问题。

public class MyThread extends Thread {

public MyThread(String name){
    this.setName(name);
        System.out.println("构造方法:"+this.currentThread().getName()+"调用方法"+this.getName());
    }

    @Override
    public void run (){
        System.out.println("run方法:"+this.currentThread().getName()+"调用方法"+this.getName());
    }
}

public class Run {
    public static void main(String[] args) {
        MyThread a=new MyThread("start");
        a.start();
        MyThread b=new MyThread("run");
        b.run();
    }
}
结果:
构造方法:main调用方法start
构造方法:main调用方法run
run方法:main调用方法run
run方法:start调用方法start

你可能感兴趣的:(java)