Java多线程

1.多线程

实现方法:

一、继承Thread,重写run方法,调用start即可。

Class Thread1 extends Thread{

       Public void run(){

              //添加代码

}

}

Public static void main(String[] args){

       Thread1 st = new Thread1();

       St.start();

}

二、实现runnable接口,重写run方法,调用start。

Class RunThrad implements runnable{

       Public void run(){

              //添加代码

}

}

RunThread t = new RunThread();

Thread th = new Thread(t);

th.start();

三、实现Callable接口类,并重写call方法,使用FutureTask类来包装Callable实现类的对象,并且使用FutureTask对象来作为Thread对象的target来创建线程。

class  Mycallable  implements  Callable<Integer>{

       Public int call(){

              //添加代码

}

}

public static void main(String[] args){

       Mycallable<Integer> mycall = new Mycallable<Integer>();

       FutureTask<Integer> ft = new FutureTask<Integer>(mycall);

       Thread th = new Thread(ft);

       th.start();

}

实现runnable和callable比继承Thread方法的优势:

1、避免单继承的问题。

2、线程池只能够放入runnable和callable类的线程。

线程主要有五种状态,如下:

 

接下来介绍sleep,wait,notify,notifyAll,join,yield六种方法

对于wait,notify,notifyAll这三个,属于object类的方法,但必须搭配synchronized同步块来使用,即在synchronized修饰的同步代码块中或者方法中调用wait或者notify/notifyAll:

由于wait,notify/notifyAll是放在同步代码块中的,所以线程在执行的时候,肯定是进入了临界状态的,即该线程肯定是获得了锁的。

当执行wait方法时,会把当前的锁释放掉,让出cpu,进入等待状态。

当执行notify/notifyAll方法时,唤醒一个等待该对象锁的线程,然后继续往下执行,直到执行完synchronized的代码后,再将锁释放。(注意,notify/notifyAll执行后,并不立即释放锁,而是需要等待执行完synchronized的代码后)

如果在线程A,线程B中,在线程A中,执行wait,在线程B中执行notify,如果线程B先执行了notify,然后就结束了,然后线程A才去执行wait,那么此时线程A就无法被唤醒了。举例如下:有3个线程A,B,C。

class T implements Runnable{

       public String i;

       public String index;

       public T(String i,String index){

              this.i = i;

              this.index = index;

       }

       @Override

       public void run() {

              synchronized (index) {

                     while (true) {

                            try {

                                   index.notifyAll();

                                   System.out.println(i);

                                   index.wait();

                            } catch (InterruptedException e) {

                                   e.printStackTrace();

                            }

                     }

              }

       }

}

public class demo {

       public static void main(String[] args){

              String string1 = "s1";

              String string2 = "s2";

              String string3 = "s3";

              String index = "test";

              T a1 = new T(string1,index);

              T a2 = new T(string2,index);

              T a3 = new T(string3,index);

              Thread thread1 = new Thread(a1);

              Thread thread2 = new Thread(a2);

              Thread thread3 = new Thread(a3);

              thread1.start();

              thread2.start();

              thread3.start();

       }

}

输出结果:

s2

s1

s3

s1

s2

s1

s3

s1

……

……

结果思考:线程不会停止。当三个线程并行启动时,s2最先抢到,进入同步代码块,这时候唤醒其他线程进行等待就绪,执行到wait方法,进入阻塞,并释放掉锁。这时候s1进入cpu,进入同步代码块,唤醒其他行程等待就绪,并执行到wait方法,并释放掉锁。进入线程循环……线程不会停止。

如果将notify方法注释掉,执行结果为

s1
s3
s2

结果思考:线程1进入同步代码块时,执行到wait方法,进入阻塞状态,无法被唤醒。线程2启动并进入阻塞,线程2启动并进入阻塞。

 

posted @ 2017-08-04 10:32  pastrytime  阅读(145)  评论(0编辑  收藏  举报