Java中多线程

Java中多线程所谓多线程,就是说一个应用程序有多条执行路径,每当我们打开一个应用程序的时候,就像当与打开了一个进程,而进程中执行的操作,就是线程。以迅雷为例,打开迅雷就相当于打开一个进程,下载文件的操作就是线程,多线程就是同时下载多个文件在Java中有两种方式实现多线程分别是继承Thread类和实现Runnable接口目录一、继承Thread类二、实现Runnable接口三、继承Thread…

大家好,欢迎来到IT知识分享网。

所谓多线程,就是说一个应用程序有多条执行路径,每当我们打开一个应用程序的时候,就像当与打开了一个进程,而进程中执行的操作,就是线程。以迅雷为例,打开迅雷就相当于打开一个进程,下载文件的操作就是线程,多线程就是同时下载多个文件

Java中有两种方式实现多线程分别是继承Thread类和实现Runnable接口

目录

一、继承Thread类

二、实现Runnable接口

三、继承Thread类和实现Runnable方法的区别

四、线程中断interrupt()

五、线程同步synchronized()


一、继承Thread类

Thread类中有一个run方法,但是这个run方法需要我们重写,故我们需要自定义一个类来继承Thread类,然后在自定义的类中重写这个run方法,重写完了就可以创建一个对象了,用该对象去调用这个方法,但是由于这是多线程,如果是直接调用run方法,无法实现多线程,然后就有了一个新的的方法start方法供我们使用,此方法会自动调用run方法。

程序代码:

package com.hezhiying;

public class Main {

	public static void main(String[] args) {
		
		//创建多线程对象
		MyThread mt1 = new MyThread();
		MyThread mt2 = new MyThread();
		MyThread mt3 = new MyThread();

		//设置每个对象的名字
		mt1.setName("hello");
		mt2.setName("world");
		mt3.setName("java");

		//调用start()方法,其内部调用了run()方法,实现了多线程
		//在这里直接调用run()方法,不能实现多线程 
		mt1.start();
		mt2.start();
		mt3.start();
	}
}

class MyThread extends Thread {
	public void run() {
		for (int x = 0; x < 100; x++) {
			System.out.println(getName() + ":" + x);
		}
	}
}

运行结果:

 Java中多线程

由结果可以看出,在跑这个循环的时候,并不是mt1跑完再跑mt2,而是抢着跑的,这就是多线程的体现,也就是抢

二、实现Runnable接口

为了解决单继承的局限性,因为如果某个类已经有父亲了,那么它就不能再继承Thread来实现多线程了,所以就有了实现接口的多线程,我们大部分使用的方法也是用接口来实现多线程。接口方式实现多线程我们需要自定义一个类去实现Runnable接口,然后在自定义的类中重写run方法,再然后去创建一个自定义类的对象,最后创建一个Thread类的对象,并且把刚刚创建的自定义对象作为参数传递

程序代码:

package com.hezhiying;

public class Main {

	public static void main(String[] args) {
                //在这里只需创造一个接口子类对象,后面直接用mr就行了
		MyRunnable mr = new MyRunnable();
		
//		Thread t1 = new Thread(mr);
//		Thread t2 = new Thread(mr);
//		t1.setName("hello");
//		t2.setName("java");
		
		//上面这种方法不是很常用,可以用下面这个
		Thread t1 = new Thread(mr,"hello");
		Thread t2 = new Thread(mr,"java");
		t1.start();
		t2.start();
		
	}
}

class MyRunnable implements Runnable {
	public void run() {
		for (int x = 0; x < 100; x++) {
			//因为Runnable中没有getName方法,故用Thread中方法获取当前线程对象来实现
			System.out.println(Thread.currentThread().getName() + ":" + x);
		}
	}
}

运行结果:

Java中多线程

三、继承Thread类和实现Runnable方法的区别

  • 继承Thread类不适合资源的共享,而实现Runnable接口很容易实现资源的共享
  • 实现Runnable接口适合多个相同的程序代码的线程去处理同一个资源
  • 避免了Java中的单继承限制
  • 增强了程序的健壮性,代码可以被多个线程共享

四、线程中断interrupt()

程序代码:

package com.hezhiying;

public class Main {

	public static void main(String[] args) {
		MyThread mt = new MyThread();

		mt.start();
		try {
			Thread.sleep(1000);
			mt.interrupt();// 这里的意思是线程执行如果超过1秒就被中断
		} catch (InterruptedException e) {
			// e.printStackTrace();
			System.out.println("中断线程");
		}

	}
}

class MyThread extends Thread {

	public void run() {
		System.out.println("线程开始");
		try {
			// 在这里是线程休息2秒,如果线程在2秒内被中断,则执行catch
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// e.printStackTrace();
			System.out.println("线程中断");
		}
		System.out.println("线程结束");
	}
}

运行结果:

Java中多线程

五、线程同步synchronized()

多线程中,线程同步问题,为了讲解此问题,举一个火车卖票的例子,假如有3个窗口卖100张票,然后消费者去买票,当然了是三个窗口同时卖票,模拟一下此过程

package com.hezhiying;

public class Main {

	public static void main(String[] args) {

		// 创建一个MyRunnable类的对象,由于此对象没有继承Thread类,所以下面还需创建Thread对象
		MyRunnable mr = new MyRunnable();

		// 用此对象去创建Thread对象,并且给每个对象赋值,也就是起个名子
		Thread t1 = new Thread(mr, "hello");
		Thread t2 = new Thread(mr, "world");
		Thread t3 = new Thread(mr, "java");

		// 这里是启动线程的意思
		t1.start();
		t2.start();
		t3.start();
	}
}

/*
 * 自定义一个类来实现Runnable接口,并重写此接口中的run方法
 */
class MyRunnable implements Runnable {

	private int t = 100;

	@Override
	public void run() {
		// 为了演示多线程的同步问题,在多线程同步中,
		// 可能出现1号窗口还正在卖,而还没卖出去的时候,二号窗口刚好开始卖,导致一张票卖了两次
		// 所以在这里我加上在卖票时候的一个延迟

		while (t > 0) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			// 这里调用的是当前线程的名字
			System.out.println(Thread.currentThread().getName() + ":" + t--);
		}
	}
}

运行结果:

Java中多线程

从上面的结果很容易看出,第100张票卖了3次,这肯定是不符合实际的,所以我们需要解决此问题,就是在某个窗口卖该张票的时候,其他窗口不能卖,也就是对该票进行加锁,即用synchronized()方法,其中有两种方式实现同步,分别是同步代码块和同步方法

package com.hezhiying;

public class Main {

	public static void main(String[] args) {

		// 创建一个MyRunnable类的对象,由于此对象没有继承Thread类,所以下面还需创建Thread对象
		MyRunnable mr = new MyRunnable();

		// 用此对象去创建Thread对象,并且给每个对象赋值,也就是起个名子
		Thread t1 = new Thread(mr, "hello");
		Thread t2 = new Thread(mr, "world");
		Thread t3 = new Thread(mr, "java");

		// 这里是启动线程的意思
		t1.start();
		t2.start();
		t3.start();
	}
}

/*
 * 自定义一个类来实现Runnable接口,并重写此接口中的run方法
 */
class MyRunnable implements Runnable {

	private int t = 100;

	// 为了演示多线程的同步问题,在多线程同步中,
	// 可能出现1号窗口还正在卖,而还没卖出去的时候,二号窗口刚好开始卖,导致一张票卖了两次
	// 所以在这里我加上在卖票时候的一个延迟

	// 方法一同步代码块
//	public void run() {
//		while (t > 0) {

	// 同步对象的锁是this
//			synchronized (this) {
//				if (t > 0) {// 在这里可能出现在t--之前进来消费者,故加个判断
//					try {
//						Thread.sleep(100);
//					} catch (InterruptedException e) {
//						e.printStackTrace();
//					}
//					// 这里调用的是当前线程的名字
//					System.out.println(Thread.currentThread().getName() + ":" + t--);
//				}
//			}
//		}
//	}

	// 方法二同步方法
	public void run() {
		while (t > 0) {
			sellt();
		}
	}

	// 此方法为同步方法
	private synchronized void sellt() {
		if (t > 0) {// 在这里可能出现在t--之前进来消费者,故加个判断
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			// 这里调用的是当前线程的名字
			System.out.println(Thread.currentThread().getName() + ":" + t--);
		}
	}
}

运行结果:

Java中多线程

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/21788.html

(0)
上一篇 2024-01-15 13:00
下一篇 2024-01-15 15:45

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信