------- http://www.itheima.com" target="blank">android培训http://www.itheima.com"target="blank">java培训、期待与您交流!
基础知识概述
<span style="font-family:Microsoft YaHei;font-size:14px;">package com.hyx;
/* 一、关于进程和线程
* 进程:正在运行的程序,是系统进行资源分配和调用的独立单位;每一个进程都有它自己的内存空间和系统资源。
* 线程:是进程中的单个顺序控制流,是一条执行路径;一个进程如果只有一条执行路径,则称为单线程程序;一个进程如果有多条执行路径,则称为多线程程序。
*
* 二、关于并行和开发
* 并行:前者是逻辑上同时发生,指在某一个时间内同时运行多个程序。
* 并发:后者是物理上同时发生,指在某一个时间点同时运行多个程序。
*
* 三、Java程序的运行原理:
* 由java命令启动JVM,JVM启动就相当于启动了一个进程;接着由该进程创建了一个主线程去调用main方法。
*
* Java虚拟机的启动也是多线程的:至少有两个,主线程和垃圾回收线程。启动垃圾回收线程的原因是为了防止内存溢出。
*
* 四、实现多线程的三种方式:
* 1.继承Thread类:
* 步骤:自定义类继承Thread类--->自定义类重写run()方法--->创建自定义类对象--->调用start()方法启动线程
* 2.实现Runnable
* 步骤:自定义类是想Runnable接口--->自定义类重写run()方法--->创建自定义类对象;创建Thread类对象并将自定
* 义类对象作为实参传入Thread类中--->调用Thread类的start()方法启动线程new Thread(new MyThread()).start();
* 3.实现Callable接口(JDK5)
*
* 五、该类为什么要重写run()方法呢?
* 不是类中所有的代码都需要被线程执行的;为了区分哪些代码能够被执行,java提供了Thread类中的run()方法用来包含那些被线程执行的代码。
*
* 六、同步有三种方式:1.同步代码块 2.同步方法 3.Lock锁
*
* 七、面试题:run()与start()的区别?
* run()方法:仅仅是封装被线程执行的代码,直接调用是普通方法;
* start()方法:首先启动了线程,然后再由JVM去调用该线程的run()方法。
*
* 八、线程常用方法:
* 1.线程名称:
* setName(String n):设置线程名称:
* getName():获取线程名称;
* 2.线程优先级:低-->高:1--10。默认:5
* setPriority(int n):设置优先级。如果不在1--10的范围内,则抛出异常;
* getPriority():获取线程的优先级;
* 3.线程休眠:
* sleep(int n):静态方法。单位:毫秒;
* 4.线程的加入:
* join():普通方法。其它线程会等待此线程执行完毕再执行;
* 5.线程的礼让:
* yield():静态方法。退回到"就绪"状态。很可能会被操作系统再次分配运行;
* 6.守护线程:
* setDaemon(boolean n):如果true,则为"守护线程"。当主线程结束时,守护线程也会跟着结束(但不会立即结束,会有个小缓冲)
* 7.线程的中断:
* stop():不建议使用。
* interrupt():在线程内部,当处于以下三种情况:
* Object-->wait():
* Thread-->join():
* Thread-->sleep():
* 会触发一个异常的产生;
* 九、线程的生命周期
* 创建--》就绪--》运行--》死亡;
* 当一个线程start()后,线程不会被立即执行,其出于就绪状态,等待CPU分配其运行空间。
* 十、同步
* 1.同步代码块:synchronized(被锁的对象){}
* 2.同步方法:public synchronized void show(){}
* A、静态方法内,可以包含“同步代码块”,但被锁的对象不能使用this,一般是使用此类的Class对象
* B、静态方法,可以被声明为“同步方法”。
* 3.JDK5的Lock锁:
* Lock l = ...;
* l.lock(); //加锁
* try{//同步的代码
* }finally{
* l.unlock();//释放锁
* }
* 十一、设计模式:1.简单工厂模式: 2.工厂方法模式 3.单例模式:1).饿汉式;2).懒汉式;
* 十二、线程池:JDK5
* 1.获取线程池:
* Executors中的静态方法:
* public static ExecutorService newCachedThreadPool()
* public static ExecutorService newFixedThreadPool(int nThreads)
* public static ExecutorService newSingleThreadExecutor()
* 2.ExecutorService中的方法:
* Future<?> submit(Runnable task):执行线程,并获取返回值;
* <T> Future<T> submit(Callable<T> task)
*
*/
public class MyThread {
}
</span>
通过代码演示加强认知
一、线程实现方式一:继承Thread类
<span style="font-family:Microsoft YaHei;font-size:14px;">
class Test{
public static void main(String[] args){
//创建线程对象
Thread1 t = new Thread1();
Thread1 t1 = new Thread1();
// Thread1 t2 = new Thread1();
//设置线程名称
t.setName("轻水");
t1.setName("青璃");
// t2.setName("琉夏");
//调用start()方法启动线程
t.start();
t1.start();
// t2.start();
//主方法中的程序
for (int i = 0; i < 100; i++) {
System.out.println(i);
}
}
}</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">package cn.itcast;
public class Thread1 extends Thread {
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(this.getName()+" ["+i+"]");
try {
</span>
<span style="font-family:Microsoft YaHei;font-size:14px;"> //休眠一秒钟</span>
<span style="font-family:Microsoft YaHei;font-size:14px;"> Thread1.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
</span>
二、多线程实现方式二
<span style="font-family:Microsoft YaHei;font-size:14px;">/*
* 线程实现Runnable(建议使用)
* 1.自定义实现Runnable接口;
* 2.重写run()方法;
* 3.启动线程:
* 1).实例化我们自定义类的对象;
* 2).实例化一个Thread对象,将我们的自定义对象作为参数传递给Thread的构造方法;
* 3).调用Thread对象的start()方法启动线程
*
* class Thread{
* private Runnable target = null;
* public Thread(){
* }
* public Thread(Runnable runnable){
* this.target = runnable;
* }
* public void start(){
* if(this.target == null){
* run();
* }else{
* target.run();
* }
* }
* public void run(){
* System.out.println("a");
* }
* }
*/
public class Demo {
public static void main(String[] args) {
MyRunnable myRun = new MyRunnable();
Thread t = new Thread(myRun);
t.start();
for(int k = 0 ;k < 100 ; k++){
System.out.println("k = " + k);
}
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">
public class MyRunnable implements Runnable {
@Override
public void run() {
for(int i = 0;i < 100 ; i++){
System.out.println("i = " + i);
}
}
}
</span>
三、使用同步解决并发访问的问题
<span style="font-family:Microsoft YaHei;font-size:14px;">/*
* 使用同步解决并发访问的问题:
*
* 1.在共享资源上(一般是一些方法)使用关键字:synchronized
* 2.作用:当一个线程访问时,其它线程全部列队等待;这种机制保证了这个方法在同一时刻
* 只能被一个线程访问;
* 3.synchronized语法:
* 1.同步代码块:
* synchronized(被锁的对象){
* //同步代码
* }
* 注:被锁的对象:当一个线程访问此段代码时,会将这个对象中所有的"同步代码块"和"同步方法"加锁,
* 也就意味着,一个线程访问一段同步代码块,其它线程不能访问"被锁对象"的其它"同步代码块"和"同步方法";
*/
public class Demo {
public static void main(String[] args) {
//1.实例化一个票池;
Tickets tic = new Tickets();
//2.实例化三个线程,模拟三个窗口售票
MyThread t1 = new MyThread(tic);
MyThread t2 = new MyThread(tic);
MyThread t3 = new MyThread(tic);
//3.设置线程名称
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
//4.启动线程
t1.start();
t2.start();
t3.start();
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">
import java.util.TreeSet;
public class MyThread extends Thread{
private Tickets tic;
private int count;
private TreeSet<Integer> tree = new TreeSet<>();
public MyThread(Tickets t){
this.tic = t;
};
public void run() {
while(true){
int t = this.tic.getTicket();
if(t > 0){
// System.out.println(this.getName() + " 抢到票:" + t);
tree.add(t);
}else{
// System.out.println("没票了,不抢了");
break;
}
}
System.out.println(this.getName() + " 共抢到 : " + tree.size() + " 张票,明细:" + tree);
}
}
</span>
<span style="font-family:Microsoft YaHei;font-size:14px;">
public class Tickets {
private int ticketNo = 100;
public int getTicket(){//窗口1
synchronized (this) {
if(this.ticketNo > 0){//窗口1
return this.ticketNo--;//窗口1
}else{
return 0;
}
}
}
}
</span>
四、单例设计模式面试题
<span style="font-family:Microsoft YaHei;font-size:14px;">/*
单例设计:饿汉式、懒汉式
重点:懒汉式
面试题:1.问:懒汉式和饿汉式有什么不同?
答;懒汉式的特点在于实例的延迟加载。
2.问:懒汉式的延迟加载有没有问题?
答:有,如果多线程访问时会出现安全问题。
3.问:怎么解决?
答:可以通过加同步来解决。
4.问:加同步的方式?
答:用同步代码块可以,但效率有点低;可以用
双重判断的方式提高效率。
5.加同步的时候使用的锁是:该类所属的字节码文件
*/
//饿汉式
class Single
{
private static final Single s = new Single();
private Single(){
}
public static Single getInstance(){
return s;
}
}
//懒汉式
class Single
{
private static Single s =null;
private Single(){
}
public static Single getInstance(){
if (s==null){
synchronized(Single.class){
if(s==null)
s = new Single();
}
}
return s;
}
}</span>