Java多线程初识

Java中线程实现的两种方法:

(一)继承Thread类  

注意事项:(1)要正确启动线程,不能直接调用run()方法,而应该调用从Thread类中继承而来的start()方法。

    (2)通过继承Thread类实现的多线程,一个类实例只能调用一次start()方法,若调用多次,则会抛出异常。

(二)继承Runnable接口

启动线程使用Thread类中的Thread构造方法。


(三)Thread类和Runnable接口

Thread类定义:public class Thread extends Object implements Runnable

可见Thread类是Runnable接口的子类,Thread类中的run()方法调用的是Runnable接口中的run()方法。


两者使用中的区别:

一个类继承Thread类,则不适合多个线程共享资源,而实现Runnable接口,可以方便的实现资源共享。


(四)代码实例

(1)继承Thread实例:

package demo1;

class MyThread extends Thread{
	private String threadName;
	private int num=4;
	
	/**
	 * @param threadName
	 */
	public MyThread(String threadName) {
		super();
		this.threadName = threadName;
	}

	public void run(){
		for(int i=0;i<10;i++){
			if(num>=0){
				System.out.println(threadName+":"+num--);
			}
		}
	}
}
public class Threaddemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread thread1=new MyThread("Thread 1");
		MyThread thread2=new MyThread("Thread 2");
		thread1.start();
		thread2.start();
	}

}

运行结果(不确定):

Thread 1:4
Thread 2:4
Thread 1:3
Thread 2:3
Thread 1:2
Thread 2:2
Thread 1:1
Thread 2:1
Thread 1:0
Thread 2:0


2)继承Runnable实例:

package demo1;

class MyRunnable implements Runnable{
	private String threadName;
	private int num=4;
	
	/**
	 * @param threadName
	 */
	public MyRunnable(String threadName) {
		super();
		this.threadName = threadName;
	}

	public void run(){
		for(int i=0;i<5;i++){
			if(num>=0){
				System.out.println(threadName+": "+num--);
			}		
		}
	}
}
public class Runnabledemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyRunnable thread=new MyRunnable("Thread");
		Thread th1=new Thread(thread);
		Thread th2=new Thread(thread);
		th1.start();
		th2.start();
	}

}


运行结果(不确定):

Thread: 4
Thread: 3
Thread: 2
Thread: 1
Thread: 0


从上面可以看出,继承Runnable接口实现的多线程,使用Thread类的构造方法来初始化,并使用start()方法来启动线程。同时可以看出继承Runnable接口实现的多线程在共享资源方面的优点。


(五)多线程异常输出

上面继承Runnable实现的多线程会出现负数或者类似两个1的情况,原理为线程资源共享时没有使用同步互斥方法,比如在线程1在还没有对num进行减1操作之前,线程2已经将num减1,但是上面的代码出现这种情况概率很小,我们可以通过sleep函数增大出现这种情况的概率。

代码:

package demo1;

class MyRunnable implements Runnable{
	private String threadName;
	private int num=4;
	
	/**
	 * @param threadName
	 */
	public MyRunnable(String threadName) {
		super();
		this.threadName = threadName;
	}

	public void run(){
		for(int i=0;i<5;i++){
			if(num>=0){
				try{
					Thread.sleep(200);
					}catch (Exception e){
					System.out.println("Sleep Error!");
					}
				System.out.println(threadName+": "+num--);
			}		
		}
	}
}
public class Runnabledemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyRunnable thread=new MyRunnable("Thread");
		Thread th1=new Thread(thread);
		Thread th2=new Thread(thread);
		th1.start();
		th2.start();
	}

}

实际运行出的结果:

(1)

Thread: 4
Thread: 3
Thread: 2
Thread: 1
Thread: -1
Thread: 0

(2)

Thread: 4
Thread: 3
Thread: 2
Thread: 1
Thread: 0
Thread: -1

(3)

Thread: 3
Thread: 4
Thread: 2
Thread: 2
Thread: 1
Thread: 0

从上面结果我们看到出现了上面提到的异常情况。这里也告诫我们在多线程资源共享情况下必须要使用同步与互斥手段对共享资源进行保护。


(六)java同步方法

(1)同步代码块

语法:

synchronized (同步对象){
             需要同步的代码
}

一般使用this指代同步对象。

代码:

package demo1;

class MyRunnable implements Runnable{
	private String threadName;
	private int num=4;
	
	/**
	 * @param threadName
	 */
	public MyRunnable(String threadName) {
		super();
		this.threadName = threadName;
	}

	public void run(){
		for(int i=0;i<5;i++){
			synchronized(this){
				if(num>=0){
					try{
						Thread.sleep(200);
						}catch (Exception e){
						System.out.println("Sleep Error!");
						}
					System.out.println(threadName+": "+num--);
				}
			}
		}
	}
}
public class Runnabledemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyRunnable thread=new MyRunnable("Thread");
		Thread th1=new Thread(thread);
		Thread th2=new Thread(thread);
		th1.start();
		th2.start();
	}

}


运行结果:

Thread: 4
Thread: 3
Thread: 2
Thread: 1
Thread: 0


(2)同步方法

语法:

synchronized 方法返回值  方法名(参数){
             需要同步的代码
}
可见同步方法只是将需要同步的代码封装在一个方法里面,本质与同步代码块一致。



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值