Java多线程理解
Java实现多线程的两种方式分别是继承Thread类和实现Runnable接口。
代码示例:
class MyThread extends Thread{ private String name; public MyThread(String name){ this.name = name; } @Override public void run(){ for(int i=0;i<7;i++){ System.out.println("线程开始:"+this.name+"次数"+i); } } }
class MyRun implements Runnable{ @Override public void run(){ for(int i=0;i<7;i++){ System.out.println("线程开始:"+Thread.currentThread().getName()+"次数"+i); } } }
public class A{ public static void main(String [] args){ MyThread myThread = new MyThread("myThread"); myThread.start(); MyRun myRun = new MyRun(); Thread run1 = new Thread(myRun, "myRun"); run1.start(); } }运行结果:
关键点1:启动线程使用start()方法,使用run()方法并不会启动新线程。
public class A{ public static void main(String [] args){ MyThread myThread1 = new MyThread(); myThread1.run(); MyThread myThread2 = new MyThread(); myThread2.run(); } }
class MyThread extends Thread{ public void run(){ for(int i=0;i<7;i++){ System.out.println("线程:"+Thread.currentThread().getName()+"次数"+i); } } }
start() : 通过调用start0()启动一个新线程,新线程会执行相应的run()方法。start()不能被重复调用。
run(): run()和普通的成员方法一样可重复调用。单独调用run()会在当前线程中执行run(),并不会启动新线程!
相关源码:
public synchronized void start() { if (threadStatus != 0) //start()方法不能被重复调用,否则会抛出异常 throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); //加入到线程组中 boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } } } private native void start0(); @Override public void run() { if (target != null) { //target是当前的Runnable对象 target.run(); } }
关键点2:Thread实现多线程与Runnable实现多线程的区别.
卖票问题:
1:Thread
class MyThread extends Thread{ private int tickets =5; @Override public void run() { while (tickets>0) { tickets--; System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数:"+tickets); } } }
public static void main(String [] args){ MyThread myThread1 = new MyThread(); myThread1.start(); MyThread myThread2 = new MyThread(); myThread2.start(); }
2:Runnable
class MyThread extends Thread{ private int tickets =5; @Override public void run() { while (tickets>0) { tickets--; System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数:"+tickets); } } }
public static void main(String [] args){ MyRunnable r = new MyRunnable(); Thread t1 = new Thread(r); Thread t2 = new Thread(r); t1.start(); t2.start(); }
MyRunnable对象只有一个,多线程共享同一对象,所以卖票结果好像是正确的。
关键点3:通过实现Runnable接口共享资源。
class MyRunnable implements Runnable{ private int tickets =10; @Override public void run() { while (tickets>0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } tickets--; System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数:"+tickets); } } }
显然最后剩余票数-1和-2是不正确的,所以仅仅实现Runnable接口是无法进行资源共享的,如果需要共享还是需要加入synchronized关键字。
class MyRunnable implements Runnable{ private int tickets =10; @Override public void run() { synchronized(this){ while (tickets>0) { tickets--; System.out.println(Thread.currentThread().getName()+"卖了一张票,剩余票数:"+tickets); } } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。