23 API-多线程(多线程概述,多线程实现方案,线程控制常见方法,线程安全问题及解决)

1:多线程(理解)

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

              进程:正在执行的应用程序

              线程:进程的执行单元,执行路径

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

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

             

              多进程的意义?

                     提高CPU的使用率

              多线程的意义?

                     提高应用程序的使用率

*多线程的存在,不是提高程序的执行速度。其实是为了提高应用程序的使用率。

* 程序的执行其实都是在抢CPU的资源,CPU的执行权。

* 多个进程是在抢这个资源,而其中的某一个进程如果执行路径比较多,就会有更高的几率抢到CPU的执行权。

* 我们是不敢保证哪一个线程能够在哪个时刻抢到,所以线程的执行有随机性。

*  注意两个词汇的区别:并行和并发。

*            前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。

*            后者是物理上同时发生,指在某一个时间点同时运行多个程序。


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

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

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


(3)多线程的实现方案(掌握)


*public final String getName():获取线程的名称
*public final void setName(String name):设置线程的名称
 针对不是Thread类的子类中如何获取线程对象名称呢?
* public static Thread currentThread():返回当前正在执行的线程对象

* Thread.currentThread().getName()

A:继承Thread类

public class MyThread extends Thread {

	@Override
	public void run() {
		// 线程执行代码		
		}
	}
}
public class MyThreadDemo {
	public static void main(String[] args) {
		// 创建线程对象
		// MyThread my = new MyThread();
		// // 启动线程
		// my.run();
		// my.run();
		// 调用run()方法为什么是单线程的呢?
		// 因为run()方法直接调用其实就相当于普通的方法调用,所以你看到的是单线程的效果
		// 要想看到多线程的效果,就必须说说另一个方法:start()
		// 面试题:run()和start()的区别?
		// run():仅仅是封装被线程执行的代码,直接调用是普通方法
		// start():首先启动了线程,然后再由jvm去调用该线程的run()方法。
		// MyThread my = new MyThread();
		// my.start();
		// // IllegalThreadStateException:非法的线程状态异常
		// // 为什么呢?因为这个相当于是my线程被调用了两次。而不是两个线程启动。
		// my.start();

		// 创建两个线程对象
		MyThread my1 = new MyThread();
		MyThread my2 = new MyThread();

		my1.start();
		my2.start();
	}
}



B:实现Runnable接口

public class MyRunnable implements Runnable {

	@Override
	public void run() {
		
			// 由于实现接口的方式就不能直接使用Thread类的方法了,但是可以间接的使用			
		
	}

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

		// 创建Thread类的对象,并把C步骤的对象作为构造参数传递
		// Thread(Runnable target)
		// Thread t1 = new Thread(my);
		// Thread t2 = new Thread(my);
		// t1.setName("林青霞");
		// t2.setName("刘意");

		// Thread(Runnable target, String name)
		Thread t1 = new Thread(my, "林青霞");
		Thread t2 = new Thread(my, "刘意");

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


(4)线程的调度和优先级问题

              A:线程的调度

                     a:分时调度

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

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

                     a:默认是5

                     b:范围是1-10


(5)线程的控制(常见方法)

A:休眠线程

* public static void sleep(long millis)  休眠线程

B:加入线程    

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

C:礼让线程

* public static void yield():暂停当前正在执行的线程对象,并执行其他线程。 

* 让多个线程的执行更和谐,但是不能靠它保证一人一次。

D:后台线程(守护线程)

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

* 当正在运行的线程都是守护线程时,Java 虚拟机退出。 该方法必须在启动线程前调用。

E:终止线程(掌握)

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

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

(6)线程的生命周期(参照线程生命周期图解.bmp)


A:新建
B:就绪
C:运行
D:阻塞
E:死亡
(7)电影院卖票程序的实现
A:继承Thread类
B:实现Runnable接口
(8)电影院卖票程序出问题
1:为了更符合真实的场景,加入了休眠100毫秒。
2:卖票问题
* A:相同的票卖了多次

* CPU的一次操作必须是原子性的

* B:出现了负数票

* 随机性和延迟导致的

(9)多线程安全问题的原因(也是我们以后判断一个程序是否有线程安全问题的依据)

A:是否有多线程环境
B:是否有共享数据
C:是否有多条语句操作共享数据

(10)同步解决线程安全问题

              A:同步代码块

                     synchronized(对象) {

                            需要被同步的代码;

                     }

                    

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

                    

              B:同步方法

                     把同步加在方法上。

                    

                     这里的锁对象是this

                    

              C:静态同步方法

                     把同步加在方法上。

                    

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


(11)回顾以前的线程安全的类

A:StringBuffer
B:Vector
C:Hashtable
D:如何把一个线程不安全的集合类变成一个线程安全的集合类

用Collections工具类的方法即可。

	// 线程安全的类
		StringBuffer sb = new StringBuffer();
		Vector<String> v = new Vector<String>();
		Hashtable<String, String> h = new Hashtable<String, String>();

		// Vector是线程安全的时候才去考虑使用的,但是我还说过即使要安全,我也不用你
		// 那么到底用谁呢?
		// public static <T> List<T> synchronizedList(List<T> list)
		List<String> list1 = new ArrayList<String>();// 线程不安全
		List<String> list2 = Collections
				.synchronizedList(new ArrayList<String>()); // 线程安全


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值