在这里先讲讲为啥要复习,还做笔记,在一起学java的时候,跟着老师视频敲打一边后,然后自己能自己写一遍就完事了,也没怎么练习,导致现在用到一些知识的时候知道但想不起来,当时也没有良好的编程习惯于做笔记的习惯,但是现在作为复习,理应做好笔记。
程序、进程、线程的概念
程序(Program) 是完成特定任务,用某种语言编写的一组指令结合。即一段静态代码,静态对象。
进程(process) 是程序的一次执行过程,或者是一个正在运行的一个程序。
线程(thread) 是进程的进一步细化,是一个程序内部的一条执行路径。
创建一个子线程,完成1-100输出,同时主线程也做同样操作
/**
* 创建一个子线程,完成1-100输出,同时主线程也做同样操作
* 创建多多线程的第一种方式,继承java.lang.Thread类
* @author tg_z
*
*/
//1.创建一个继承Thread 的子类
class SubThread extends Thread {
// 2.重写Thread 类的run() 方法
@Override
public void run() {
// 里面子线程要做的事
for (int i = 1; i <= 100; i++) {
System.out.println(i);
}
}
}
public class TestThread {
public static void main(String[] args) {
//3.创建一个子类对象
SubThread subThread = new SubThread();
//4.调用线程的start(),启动线程,调用相应的run()方法。
subThread.start();
//主线程操作
for (int i = 1; i <= 100; i++) {
System.out.println("主线程 i="+i);
}
}
}
/**
* 创建一个子线程,完成1-100输出,同时主线程也做同样操作
* 创建多多线程的第二种方式,实现方式
* @author tg_z
*
*/
class SubThread2 implements Runnable {
@Override
public void run() {
// 里面子线程要做的事
for (int i = 1; i <= 100; i++) {
System.out.println(i);
}
}
}
public class TestThread2 {
public static void main(String[] args) {
SubThread2 subThread2 = new SubThread2();
Thread thread = new Thread(subThread2);
thread.start();
Thread thread2 = new Thread(subThread2);
thread2.start();
//主线程操作
for (int i = 1; i <= 100; i++) {
System.out.println("主线程 i="+i);
}
}
}
两种对比:
1.联系
public class Thread implements Runnable
2.那种方式好?
实现的方式优于继承方式,因为实现方式避免Java单继承的局限性。多个线程操作同一份资源更适合使用实现的方式。
Thread 的常用方法
/**
* Thread 常用方法
* 1.stat() 启动线程并执行的相应run方法
* 2.run() 子线程要执行的代码放入run()里面
* 3.currentThread() 静态的,调用当前的线程
* 4.getName() 获取此线程名字
* 5.setName() 设置此线程名字
* 6.yield() 释放当前CPU的执行权
* 7.join() 在A线程中调用B线程join 方法,表示A线程停止执行,
* 直至B线程执行完毕,A再接着join之后代码执行
* 8.isAlive() 判断当前进程是否存活
* 9.sleep(long l) 显示让当前进程睡眠l 毫秒
* 10 :线程通信 wait() notify() notifyAll()
*
* @author tg_z
*
*/
class SubThread1 extends Thread {
@Override
public void run() {
// 里面子线程要做的事
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + i);
if(i%10==0) {
Thread.currentThread().yield();
}
}
}
}
public class TestThread1 {
public static void main(String[] args) {
SubThread1 subThread = new SubThread1();
subThread.setName("子线程");
subThread.start();
Thread.currentThread().setName("这是主线程");
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName()+" "+i);
if(i == 20) {
try {
subThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
线程调度优先级
调度策略
- 时间片
- 抢占式 : 高优先级的线程抢占CPU
java的调度方法
- 同级优先级组成先进先出队列(先来先服务),时间片策略
- 优先级高,使用抢占式策略
线程的优先级
涉及方法:
- getPriority():返回线程优先值(1-10)
- setPriority(int newPriority) 改变线程的优先级
线程创建时继承父线程的优先级
使用多线程的优点
- 提高应用程序的相应。
- 提过计算机系统CPU的利用率
- 改善程序结构。
线程的生命周期
线程安全
线程安全存在的原因?
- 由于一个线程操作共享数据过程中,未执行完毕的情况下,另外的线程参与进来导致共享数据存在安全问题。
如何解决线程安全问题?
- 让一个线程操作共享数据完成后其他线程才有机会参与共享数据操作。
java实现线程安全问题:线程同步(原理必须知道)
- 方式一 同步代码块
synchronized(同步监视器){
//需要被同步的代码块(操作共享数据的代码)
}
//同步监视器:有一个类的对象来充当,那个线程获得此监视器,就执行同步代码块 即 锁
//要求所有线程共用一把锁
- 方式二 同步方法
将操作共享数据的方法声明为synchronized . 即同步方法,使一个线程执行此方法是其他线程等待。
--同步方法的锁:this
public void run(){
方法1();
}
public synchronized 方法1(){
//需要被同步的代码块(操作共享数据的代码)
}
单例模式值懒汉式线程安全问题
- 单例模式
//
class Singleton {
private static Singleton sinleton= null;
private Singleton() {
}
public static Singleton getSingleton() {
if(sinleton == null) {
sinleton = new Singleton();
}
return sinleton;
}
}
public class TestSingleton {
public static void main(String[] args) {
Singleton sinleton = Singleton.getSingleton();
Singleton sinleto1 = Singleton.getSingleton();
if(sinleton == sinleto1) {
System.out.println("true");
}
}
}
- 线程安全
当多个线程来创建时,会发生线程安全问题,解决方法:
//
class Singleton {
private static Singleton sinleton = null;
private Singleton() {
}
public static Singleton getSingleton() {
//提高效率,防止盲目等待
if (sinleton == null) {
//解决线程安全
synchronized (Singleton.class) {
if (sinleton == null) {
sinleton = new Singleton();
}
}
}
return sinleton;
}
}
public class TestSingleton {
public static void main(String[] args) {
Singleton sinleton = Singleton.getSingleton();
Singleton sinleto1 = Singleton.getSingleton();
if (sinleton == sinleto1) {
System.out.println("true");
}
}
}
死锁
- 概念
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。 - 解决方法
专门算法,原则
尽量减少同步资源定义
线程通信
wait()与notify()和notifyAll()
三个关键字的使用都得到同步代码块或同步方法中使用
class PrintNum implements Runnable {
int num = 1;
public void run() {
while (num <= 100) {
synchronized (this) {
//唤醒
notify();
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " num=" + num);
num++;
// 执行完释放
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
}
public class TestCommunication {
public static void main(String[] args) {
PrintNum printnum = new PrintNum();
Thread thread = new Thread(printnum);
Thread thread2 = new Thread(printnum);
thread.setName("thread");
thread2.setName("thread2");
thread.start();
thread2.start();
}
}