java基础--多线程



1、多线程:一个应用程序有多条执行路径

进程:正在执行的应用程序,是系统进行资源分配和调用的独立单位

线程:是进程中的单个顺序控制流,是一条执行路径

单线程:一个应用程序只有一条执行路径

多线程:一个应用程序有多条执行路径

多进程的意义?

提高CPU的使用率

多线程的意义?

提高应用程序的使用率

2、Java程序的运行原理及JVM的启动是多线程的吗?

A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程

B:JVM的启动是多线程的,因为它最低有两个线程启动了,主线程和垃圾回收线程

3、多线程的实现方案

A:继承Thread类

步骤:

a.自定义类MyThread继承Thread类

b.B:MyThread类里面重写run()

c.创建对象

d.启动线程:对象名.start()

public class MyThreadDemo {

	public static void main(String[] args) {

		MyThread my1 = new MyThread();
		MyThread my2 = new MyThread();

		my1.start();  //调用第一个线程
		my2.start();  //调用第二个线程
	}

}

class MyThread extends Thread {

	public MyThread() {
	}

	public MyThread(String name) {
		super(name);
	}

	@Override
	public void run() {   //重写的方法
		for (int x = 0; x < 100; x++) {
			System.out.println(getName() + ":" + x);
		}
	}
}

B:实现Runnable接口

步骤:

a.自定义类MyRunnable实现Runnable接口

b.重写run()方法

c.创建MyRunnable类的对象

d.创建Thread类的对象,并把C步骤的对象作为构造参数传递

public class MyRunnableDemo {
	public static void main(String[] args) {
		// 创建MyRunnable类的对象
		MyRunnable my = new MyRunnable();

		Thread t1 = new Thread(my, "张三");
		Thread t2 = new Thread(my, "李四");

		t1.start();
		t2.start();
	}
}

class MyRunnable implements Runnable {

	@Override
	public void run() {
		for (int x = 0; x < 10; x++) {
			// 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用
			System.out.println(Thread.currentThread().getName() + ":" + x);
		}
	}

}

4、获取线程名称

A;获取

public final String getName():获取线程的名称

B:设置

public final void setName(String name):设置线程的名称

C:当前线程

public static Thread currentThread():返回当前正在执行的线程对象

Thread.currentThread().getName()  当前线程名称

5、线程的调度和优先级问题

A:线程的调度

a:分时调度

b:抢占式调度 (Java采用的是该调度方式)

B:获取和设置线程优先级

a:默认是5

b:范围是1-10

c:方法

public final int getPriority():返回线程对象的优先级

public final void setPriority(int newPriority):更改线程的优先级

6、线程的控制(常见方法)

A:休眠线程

public static void sleep(long millis)

B:加入线程

public final void join():等待该线程终止

C:礼让线程

public static void yield():暂停当前正在执行的线程对象,并执行其他线程;让多个线程的执行更和谐,但是不能靠它保证一人一次

D:后台线程

public final void setDaemon(boolean on):将该线程标记为守护线程或用户线程

E:终止线程

public final void stop():让线程停止,过时了,但是还可以使用

 public void interrupt():中断线程。 把线程的状态终止,并抛出一个InterruptedException

7、线程的生命周期

A:新建

B:就绪

C:运行

D:阻塞

E:死亡


8、多线程安全问题的原因

A:是否有多线程环境

B:是否有共享数据

C:是否有多条语句操作共享数据

9、同步解决线程安全问题

A:同步代码块

synchronized(对象) {

需要被同步的代码;

}

这里的锁对象可以是任意对象

B:同步方法

把同步加在方法上

这里的锁对象是this

C:静态同步方法

把同步加在方法上

这里的锁对象是当前类的字节码文件对象(反射再讲字节码文件对象)

10、电影票同步安全的案列

public class SellTicketDemo {
	public static void main(String[] args) {
		// 创建资源对象
		SellTicket st = new SellTicket();

		// 创建三个线程对象
		Thread t1 = new Thread(st, "窗口1");
		Thread t2 = new Thread(st, "窗口2");
		Thread t3 = new Thread(st, "窗口3");

		// 启动线程
		t1.start();
		t2.start();
		t3.start();
	}
}
class SellTicket implements Runnable {

	// 定义100张票
	private static int tickets = 100;

	// 定义同一把锁
	private Object obj = new Object();
	private Demo d = new Demo();

	private int x = 0;

	@Override
	public void run() {
		while (true) {
			if (x % 2 == 0) {
				synchronized (SellTicket.class) {
					if (tickets > 0) {
						try {
							Thread.sleep(100);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						System.out.println(Thread.currentThread().getName()
								+ "正在出售第" + (tickets--) + "张票 ");
					}
				}
			} else {

				sellTicket();

			}
			x++;
		}
	}
	private static synchronized void sellTicket() {
		if (tickets > 0) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName() + "正在出售第"
					+ (tickets--) + "张票 ");
		}
	}
}

class Demo {
}

11、线程安全的类

A:StringBuffer

B:Vector

C:Hashtable

D:如何把一个线程不安全的集合类变成一个线程安全的集合类

用Collections工具类的方法即可

public static <T> List<T> synchronizedList(List<T> list)

12、锁对象Lock

A:方法

void lock(): 获取锁

void unlock():释放锁

B:代码

public class SellTicket implements Runnable {

	// 定义票
	private int tickets = 100;

	// 定义锁对象
	private Lock lock = new ReentrantLock();

	@Override
	public void run() {
		while (true) {
			try {
				// 加锁
				lock.lock();
				if (tickets > 0) {
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()
							+ "正在出售第" + (tickets--) + "张票");
				}
			} finally {
				// 释放锁
				lock.unlock();
			}
		}
	}

}


13、线程组

A:把多个线程组合到一起

B:线程的方法

public final ThreadGroup getThreadGroup()  获取所属的线程组

C:线程组的方法

public final String getName()  获取所属线程组的名称

14、线程池

A:好处:

线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用

B:实现

a:创建一个线程池对象,控制要创建几个线程对象

public static ExecutorService newFixedThreadPool(int nThreads)

b:哪种线程可以执行线程组

Runnable对象或者Callable对象代表的线程

C:调用方法

Future<?> submit(Runnable task)

<T> Future<T> submit(Callable<T> task)

D:代码

public class ExecutorsDemo {
	public static void main(String[] args) {
		// 创建一个线程池对象,控制要创建几个线程对象。
		// public static ExecutorService newFixedThreadPool(int nThreads)
		ExecutorService pool = Executors.newFixedThreadPool(2);

		// 可以执行Runnable对象或者Callable对象代表的线程
		pool.submit(new MyRunnable());
		pool.submit(new MyRunnable());

		//结束线程池
		pool.shutdown();
	}
}


C:Callable接口

这是实现多线程的第三种方式

代码体现:


/*
 * 线程求和案例
 */
public class MyCallable implements Callable<Integer> {

	private int number;

	public MyCallable(int number) {
		this.number = number;
	}

	@Override
	public Integer call() throws Exception {
		int sum = 0;
		for (int x = 1; x <= number; x++) {
			sum += x;
		}
		return sum;
	}

}

public class CallableDemo {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		// 创建线程池对象
		ExecutorService pool = Executors.newFixedThreadPool(2);

		// 可以执行Runnable对象或者Callable对象代表的线程
		Future<Integer> f1 = pool.submit(new MyCallable(100));
		Future<Integer> f2 = pool.submit(new MyCallable(200));

		// V get()
		Integer i1 = f1.get();
		Integer i2 = f2.get();

		System.out.println(i1);
		System.out.println(i2);

		// 结束
		pool.shutdown();
	}
}

15、定时器

A:定时器:可以让我们在指定的时间做某件事情,还可以重复的做某件事情

B:依赖Timer和TimerTask这两个类:

Timer:定时

public Timer()

public void schedule(TimerTask task,long delay)  表示多少毫秒后执行定时任务

public void schedule(TimerTask task,long delay,long period)    表示每隔delay毫秒后第一次执行,然后每隔period毫秒后一直执行

public void cancel()  终止此计时器,丢弃所有当前已安排的任务

TimerTask:任务

C:代码体现

public class TimerDemo {
	public static void main(String[] args) {
		// 创建定时器对象
		Timer t = new Timer();
		// 3秒后执行爆炸任务
		//结束任务
		t.schedule(new MyTask(t), 3000);
	}
}

// 做一个任务
class MyTask extends TimerTask {

	private Timer t;
	
	public MyTask(){}
	
	public MyTask(Timer t){
		this.t = t;
	}
	
	@Override
	public void run() {
		System.out.println("beng,爆炸了");
		t.cancel();
	}

}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值