标签:
class hello extends Thread {
private String name;
public hello() {
}
public hello(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "运行 " + i);
}
}
}public static void main(String[] args) {
hello h1=new hello("A");
hello h2=new hello("B");
h1.start();
h2.start();
}
class hello implements Runnable {
private String name;
public hello() {
}
public hello(String name) {
this.name = name;
}
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "运行 " + i);
}
public static void main(String[] args){
hello h1=new hello("线程A");
Thread demo= new Thread(h1);
hello h2=new hello("线程B");
Thread demo1=new Thread(h2);
demo.start();
demo1.start();
}
}
其实Thread中的run方法调用的是Runnable接口的run方法,Thread和Runnable都实现了run方法,这种操作模式其实就是代理模式。
如果一个类继承Thread,则不适合实现资源共享。但是如果实现Runnable接口的话,则很容易实现资共享。
class hello extends Thread {
public void run() {
for (int i = 5; i >= 0; i--) {
System.out.println("i = " + i);
}
}
public static void main(String[] args) {
hello h1 = new hello();
hello h2 = new hello();
h1.start();
h2.start();
}
}
运行结果为:
i = 5
i = 4
i = 3
i = 2
i = 1
i = 0
i = 5
i = 4
i = 3
i = 2
i = 1
i = 0
如果使用多线程去实现一个卖票的系统,继承Thread的方法就不行了,要用Runnable的实现方式
class MyThread implements Runnable{
private int ticket = 5; //5张票
public void run() {
for (int i=0; i<=20; i++) {
if (this.ticket > 0) {
System.out.println(Thread.currentThread().getName()+ "正在卖票"+this.ticket--);
}
}
}
}
public class Test {
public static void main(String [] args) {
MyThread my = new MyThread();
new Thread(my, "1号窗口").start();
new Thread(my, "2号窗口").start();
}
}
运行结果为:
1号窗口正在卖票5
1号窗口正在卖票4
2号窗口正在卖票3
1号窗口正在卖票1
1号窗口正在卖票2
实现Runnable比继承Thread更具有的优势:
1、适合多个相同的程序的线程去处理同一个资源。
2、可避免JAVA单继承限制
3、增加程序的健壮性,代码可被多个线程共享,代码和数据独立
【main方法本身也是一个线程,JAVA的垃圾回收机制也是线程,所以程序运行至少会有两个线程运作】
class hello implements Runnable {
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args) {
hello he = new hello();
Thread thread = new Thread(he,"线程");
demo.start();
for(int i=0;i<50;++i){
if(i>10){
try{
thread.join(); //强制执行thread
}catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("main 线程执行-->"+i);
}
}
}
class hello implements Runnable {
public void run() {
for (int i = 0; i < 3; i++) {
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + i);
}
}
public static void main(String[] args) {
hello he = new hello();
Thread thread = new Thread(he, "线程");
thread.start();
}
}
class hello implements Runnable {
public void run() {
System.out.println("执行run方法");
try {
Thread.sleep(10000);
System.out.println("线程完成休眠");
} catch (Exception e) {
System.out.println("休眠被打断");
return; //返回到程序的调用处
}
System.out.println("线程正常终止");
}
public static void main(String[] args) {
hello he = new hello();
Thread thread = new Thread(he, "线程");
thread.start();
try{
Thread.sleep(2000);
}catch (Exception e) {
e.printStackTrace();
}
thread.interrupt(); //2s后中断线程
}
}
class hello implements Runnable {
public void run() {
for(int i=0;i<5;++i){
System.out.println(Thread.currentThread().getName()+"运行"+i);
}
}
public static void main(String[] args) {
Thread h1=new Thread(new hello(),"A");
Thread h2=new Thread(new hello(),"B");
h1.setPriority(8);
h2.setPriority(2);
h1.start();
h2.start();
}
}
这里注意,并不是优先级越高越先执行,而是看谁先抢到CPU,主线程的优先级为5
class hello implements Runnable {
public void run() {
for(int i=0;i<5;++i){
System.out.println(Thread.currentThread().getName()+"运行"+i);
if(i==3){
System.out.println("线程的礼让");
Thread.currentThread().yield();//通过yield方法将一个线程的操作暂时交给另一个线程执行
}
}
}
public static void main(String[] args) {
Thread h1=new Thread(new hello(),"A");
Thread h2=new Thread(new hello(),"B");
h1.start();
h2.start();
}
}
class hello implements Runnable {
public void run() {
for(int i=0;i<10;++i){
if(count>0){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(count--);
}
}
}
public static void main(String[] args) {
hello he=new hello();
Thread h1=new Thread(he);
Thread h2=new Thread(he);
Thread h3=new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count=5;
}
运行结果为:
5
4
3
2
1
0
-1
这里出现了-1,而代码判断了count>0,出现这样的情况是没有用到线程同步
线程同步就是说在同一个时间段中,只有一个线程能运行,其他线程必须等待着个线程结束后才能被执行
class hello implements Runnable {
public void run() {
for(int i=0;i<10;++i){
synchronized (this) {
if(count>0){
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
System.out.println(count--);
}
}
}
}
public static void main(String[] args) {
hello he=new hello();
Thread h1=new Thread(he);
Thread h2=new Thread(he);
Thread h3=new Thread(he);
h1.start();
h2.start();
h3.start();
}
private int count=5;
}
this 为当前对象,一般吧当前对象作为同步对象
同样也可以采用下面的代码
<div class="line number4 index3 alt1"><code class="java keyword">class</code> <code class="java plain">hello </code><code class="java keyword">implements</code> <code class="java plain">Runnable {</code></div><div class="line number5 index4 alt2"><code class="java spaces"> </code><code class="java keyword">public</code> <code class="java keyword">void</code> <code class="java plain">run() {</code></div><div class="line number6 index5 alt1"><code class="java spaces"> </code><code class="java keyword">for</code> <code class="java plain">(</code><code class="java keyword">int</code> <code class="java plain">i = </code><code class="java value">0</code><code class="java plain">; i < </code><code class="java value">10</code><code class="java plain">; ++i) {</code></div><div class="line number7 index6 alt2"><code class="java spaces"> </code><code class="java plain">sale();</code></div><div class="line number8 index7 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div><div class="line number9 index8 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div><div class="line number11 index10 alt2"><code class="java spaces"> </code><code class="java keyword">public</code> <code class="java keyword">synchronized</code> <code class="java keyword">void</code> <code class="java plain">sale() {</code></div><div class="line number12 index11 alt1"><code class="java spaces"> </code><code class="java keyword">if</code> <code class="java plain">(count > </code><code class="java value">0</code><code class="java plain">) {</code></div><div class="line number13 index12 alt2"><code class="java spaces"> </code><code class="java keyword">try</code> <code class="java plain">{</code></div><div class="line number14 index13 alt1"><code class="java spaces"> </code><code class="java plain">Thread.sleep(</code><code class="java value">1000</code><code class="java plain">);</code></div><div class="line number15 index14 alt2"><code class="java spaces"> </code><code class="java plain">} </code><code class="java keyword">catch</code> <code class="java plain">(InterruptedException e) {</code></div><div class="line number16 index15 alt1"><code class="java spaces"> </code><code class="java plain">e.printStackTrace();</code></div><div class="line number17 index16 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div><div class="line number18 index17 alt1"><code class="java spaces"> </code><code class="java plain">System.out.println(count--);</code></div><div class="line number19 index18 alt2"><code class="java spaces"> </code><code class="java plain">}</code></div><div class="line number20 index19 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div><div class="line number22 index21 alt1"><code class="java spaces"> </code><code class="java keyword">public</code> <code class="java keyword">static</code> <code class="java keyword">void</code> <code class="java plain">main(String[] args) {</code></div><div class="line number23 index22 alt2"><code class="java spaces"> </code><code class="java plain">hello he = </code><code class="java keyword">new</code> <code class="java plain">hello();</code></div><div class="line number24 index23 alt1"><code class="java spaces"> </code><code class="java plain">Thread h1 = </code><code class="java keyword">new</code> <code class="java plain">Thread(he);</code></div><div class="line number25 index24 alt2"><code class="java spaces"> </code><code class="java plain">Thread h2 = </code><code class="java keyword">new</code> <code class="java plain">Thread(he);</code></div><div class="line number26 index25 alt1"><code class="java spaces"> </code><code class="java plain">Thread h3 = </code><code class="java keyword">new</code> <code class="java plain">Thread(he);</code></div><div class="line number27 index26 alt2"><code class="java spaces"> </code><code class="java plain">h1.start();</code></div><div class="line number28 index27 alt1"><code class="java spaces"> </code><code class="java plain">h2.start();</code></div><div class="line number29 index28 alt2"><code class="java spaces"> </code><code class="java plain">h3.start();</code></div><div class="line number30 index29 alt1"><code class="java spaces"> </code><code class="java plain">}</code></div><div class="line number32 index31 alt1"><code class="java spaces"> </code><code class="java keyword">private</code> <code class="java keyword">int</code> <code class="java plain">count = </code><code class="java value">5</code><code class="java plain">;</code></div><div class="line number33 index32 alt2"><code class="java plain">}</code></div>
【当多个线程共享一个资源的时候需要同步,但是过多的同步可能会导致死锁】
1、线程中wait和sleep最大的不同是在等待时,wait会释放锁,而sleep会一直持有锁wait通常被用于线程间的交互,sleep通常用于暂停执行
2、wait方法能使线程阻塞,调用notify方法能唤醒当前备阻塞的线程
3、如果调用某个对象的wait方法,当前线程必须拥有这个对象的monitor(即锁),因此调用wait方法必须在同步块,或者同步方法中进行
4、调用某个对象的wait方法,相当于让当前线程交出此对象的monitor(即锁),然后进入等待状态,等待后继续获得此对象的锁( sleep方法则是使当前线程暂停执行一段时间,从而让其他线程有机会继续执行,但他并不会释放对象锁)
5、notify方法能够唤醒一个正在等待该对象的monitor的线程,当有多个线程都在等待该对象的monitor的话,则只能唤醒其中一个线程,具体唤醒哪个线程则不得而知
6、调用某个对象的notify方法,当前线程也必须拥有这个对象的monitor,因此调用notify()方法必须在同步块或者同步方法中进行
7、notify和notifyAll方法只是唤醒等待该对象的monitor的线程,并不决定哪个线程能够获取到monitor
标签:
原文地址:http://blog.csdn.net/wei4487835/article/details/51368134