0
点赞
收藏
分享

微信扫一扫

【Java进阶营】Java多线程基础学习(一)

**1. 创建线程   **

1.1 通过构造函数:public Thread(Runnable target, String name){}  或:public Thread(Runnable target){}

示例:

1.  Thread thread1 =  new  Thread(new  MyThread(),  "mythread");

2.  class  MyThread  extends  Thread(){

3.  public  void run(){

4.  System.out.println("My First Thread');

5.  }

6.  }

1.2 直接实现Runnable接口:

示例:

1.  Thread thread2 =  new  Thread(new  Runnable{}{

2.  public  void run(){

3.  System.out.println("This is my thread.");

4.  }

5.  });

**2. 运行线程   **

thead1.start()

3. sleep

1.  try{

2.  #休眠1000ms

3.  Thread.sleep(1000);

4.  }catch(InterruptedException e){

5.  e.printStackTrace();

6.  }

4. getName() 获取线程名字, getId()获取线程id

System.out.println(Thread.currentThread().getName() + “:”+ Thread.currentThread().getId);

5. 停止线程,

千万不用stop(),stop会立即终止线程。

通过interrupt()中断线程,但是中断并没有停止线程,配合异常来实现:

1.  public  class  Main  {

2.  public  static  void main(String[] args)  throws  InterruptedException  {

3.  try{

4.  Thread thread1=new  Thread(new  TheThread(),"thread1");

5.  thread1.start();

6.  Thread.sleep(2000);

7.  thread1.interrupt();

8.  }catch  (InterruptedException e){

9.  e.printStackTrace();

10.  }

11.  }

12.  }

13.  class  TheThread  extends  Thread{

14.  public  void run()  {

15.  super.run();

16.  for  (int i =  0; i <  10; i++)  {

17.  if(this.interrupted()){

18.  break;

19.  }

20.  System.out.println(Thread.currentThread().getName()  +  ":"  + i);

21.  }

22.  }

23.  }

注意,如果在TheThread类里加入catch InterruptException的话,可能会导致interrupt被捕获,而绕过if(this.interrupted())的判断而无法终止线程。

6. 等待和通知

线程等待:当前线程就处于等待状态,直到其他线程调用了notify()方法,线程才会继续执行

1.  public  final  void wait()  throws  InterruptedException

线程通知:

1.  public  final  native  void notify()

注意:在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出同步代码块中。

1.  package wait.notify;

3.  public  class  ThreadWaitNotifyTest  {

4.  final  static  Object  object=new  Object();

5.  public  static  class T1 extends  Thread{

6.  public  void run(){

7.  System.out.println(System.currentTimeMillis()+": T1 start");

8.  synchronized  (object){

9.  try  {

10.  System.out.println(System.currentTimeMillis()+": T1 wait");

11.  object.wait();

12.  }  catch  (InterruptedException e)  {

13.  e.printStackTrace();

14.  }

15.  }

16.  System.out.println(System.currentTimeMillis()+": T1 end");

17.  }

18.  }

19.  public  static  class T2 extends  Thread{

20.  public  void run(){

21.  System.out.println(System.currentTimeMillis()+": T2 start");

22.  synchronized  (object){

23.  System.out.println("T2 synchonized code start.");

24.  object.notify();

25.  try  {

26.  Thread.sleep(2000);

27.  }  catch  (InterruptedException e)  {

28.  e.printStackTrace();

29.  }finally{

30.  System.out.println("T2 synchonized code end.");

31.  }

33.  }

34.  try  {

35.  Thread.sleep(2000);

36.  }  catch  (InterruptedException e)  {

37.  e.printStackTrace();

38.  }

39.  System.out.println(System.currentTimeMillis()+": T2 end");

40.  }

41.  }

42.  public  static  void main(String[] args){

43.  Thread thread1=new T1();

44.  Thread thread2=new T2();

45.  thread1.start();

46.  thread2.start();

47.  }

48.  }

输出结果:

image.png

7. 线程优先级

高优先级的线程将会获得更多的CPU资源。一共分为10个优先级。

public final void setPriority(int newPriority)

源码分析:

1.  public  final  void setPriority(int newPriority)  {

2.  ThreadGroup g;

3.  checkAccess();

4.  if  (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY)  {

5.  throw  new  IllegalArgumentException();

6.  }

7.  if((g = getThreadGroup())  !=  null)  {

8.  if  (newPriority > g.getMaxPriority())  {

9.  newPriority = g.getMaxPriority();

10.  }

11.  setPriority0(priority = newPriority);

12.  }

13.  }

1.  public  final  static  int MIN_PRIORITY =  1;

2.  public  final  static  int NORM_PRIORITY =  5;

3.  public  final  static  int MAX_PRIORITY =  10;

可见线程最高优先级为10, 最低为1, 默认为5.

当设定的newPriority高于该线程组ThreadGroup的最高Priority时,只能分配该线程组的最高Priority

8. 守护线程

类似守护进程,Java存在两种线程:用户线程和守护线程。它是一种特殊线程,执行的是一种后台服务,当一个系统中不存在非守护线程的时候,守护线程会自己销毁。典型的守护线程:JVM的垃圾回收线程。

public final void setDaemon(boolean on)

示例:

1.  public  class  Main  {

2.  public  static  void main(String[] args)  throws  InterruptedException  {

3.  TheThread theThread=new  TheThread();

4.  theThread.setDaemon(true);//设置守护线程

5.  theThread.start();

6.  Thread.sleep(5000);

7.  System.out.println("全都退出啦");

8.  }

9.  public  static  class  TheThread  extends  Thread{

10.  public  void run(){

11.  int i =  0;

12.  while  (true){

13.  i++;

14.  System.out.println(Thread.currentThread().getId()+":"+i);

15.  try  {

16.  Thread.sleep(2000);

17.  }  catch  (InterruptedException e)  {

18.  e.printStackTrace();

19.  }

20.  }

21.  }

22.  }

23.  }

源码分析:

设置线程为用户线程(user thread)或守护线程(daemon thread),当剩余运行的线程均为守护线程时,JVM会退出。

1.  public  final  void setDaemon(boolean on)  {

2.  checkAccess();

3.  if  (isAlive())  {

4.  throw  new  IllegalThreadStateException();

5.  }

6.  daemon = on;

7.  }

其中checkAccesss()方法如下:

1.  public  final  void checkAccess()  {

2.  SecurityManager security =  System.getSecurityManager();

3.  if  (security !=  null)  {

4.  security.checkAccess(this);

5.  }

6.  }

该方法用于判断当前运行的线程是否有修改此线程的权限。

而public final native boolean isAlive();用于判断该线程是否处于alive状态,即该线程是否已经start,且没有die。

当isAlive的话就会抛出IllegalThreadStateException异常。

所以,设置守护线程的方法,逻辑就是先判断当前线程是否有修改的权限,再判断是否处于alive状态,如果不处于alive状态,则根据boolean变量on的值更改它的状态,即true:设为daemon线程,false:设为user线程。

举报

相关推荐

0 条评论