时间长了,并发编程的基础知识总忘,来记录一下:
进程和线程
进程:资源分配的最小单元,什么是资源?CPU,内存,网卡等等
线程:进程中的一个实体,不能单独存在,依赖进程存在。CPU调度的最小单元。
并发和并行
并发:单位时间内,多个任务交替执行。
并行:同一时刻,每个任务同时执行。多核CPU可以实现并行。
如何创建一个线程?
1,继承Thread类
package cn.tulingxueyuan.xiaoshanshan.base;
public class UseThread {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}
class MyThread extends Thread{
@Override
public void run() {
//要执行的代码
System.out.println("hello ,Thread");
}
}
2,实现Runnable接口
package cn.tulingxueyuan.xiaoshanshan.base;
public class UseRunnable {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable); // Runnable接口也要借助Thread类才能启动
thread.start();
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
// 要执行的代码
System.out.println("hello ,Runnable");
}
}
其实Thread类也实现了Runnable接口
我们在启动一个java进程的时候,main()是主线程,在main()方法中又启动了子线程,当主线程运行结束了不意味着进程就结束了,所有线程结束了进程才结束。在main线程中启动一个子线程Thread-0,主线程不会因为有子线程的执行而阻塞,main线程和线程Thread-0会并行执行。
如下图程序中,当运行该程序的时候,控制台(Terminal中)输入jconsole,可以查看线程的情况,当main()方法执行完成之后会退出,Thread-0会继续执行。当Thread-0执行结束以后,会卡死或者断开。
package cn.tulingxueyuan.xiaoshanshan.base;
public class CatThreadDemo {
public static void main(String[] args) {
Cat cat = new Cat();
cat.start();
for(int i =0 ;i<60;i++){
System.out.println(i +", 执行线程名"+Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Cat extends Thread{
int times = 0;
@Override
public void run() {
String name = Thread.currentThread().getName();
while(true){
System.out.println("喵喵,我是一只小猫猫~" + (++times) + "线程名称:" + name);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(times == 80){
break ;
}
}
}
}
线程Thread类的一些重要方法
start()方法:一个线程只有调用这个方法后,才能真正和操作系统的线程挂钩,
底层是调用了start0()方法,这个方法是native方法,即本地方法,底层是C或者C++实现的,是JVM来调用的,真正实现了多线程。
run()方法:这个方法中是要写的代码逻辑
setName()设置线程名称
getName()得到线程名称
sleep()睡眠,不会释放锁 Thread类调用的静态方法
interrupt()中断方法,不是终止方法
yiled()静态方法,礼让方法,不一定礼让成功,在Cpu资源比较紧张的时候,礼让的效果比较明显
join()线程的插队(这里有个面试题:有三个线程:t1,t2,t3,如何保证t3在t2之前完成,t2在t1之前完成)
文章来源地址https://uudwc.com/A/k6bz
package cn.tulingxueyuan.xiaoshanshan.base;
public class UseJoin {
public static void main(String[] args) {
JoinThread t1 = new JoinThread();
JoinThread t2 = new JoinThread();
JoinThread t3 = new JoinThread();
t1.setName("t1");
t2.setName("t2");
t3.setName("t3");
t1.setT(t2);
t2.setT(t3);
t1.start();
t2.start();
t3.start();
}
}
class JoinThread extends Thread{
Thread t ;
public void setT(Thread t) {
this.t = t;
}
@Override
public void run() {
if(null!=t){
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println( "线程:" + Thread.currentThread().getName() + "执行我的逻辑...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
执行结果:
守护线程:
守护线程服务于用户线程,当用户线程结束的时候,守护线程也结束了
package cn.tulingxueyuan.xiaoshanshan.base;
public class DaemonThread {
public static void main(String[] args) throws InterruptedException {
MyDaemonThread myDaemonThread = new MyDaemonThread();
myDaemonThread.setDaemon(true);
myDaemonThread.start();
for (int i =0;i<10;i++){
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "打印出:" +i);
}
}
}
class MyDaemonThread extends Thread{
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "打印出:" + Math.random()*100+1);
}
}
}
看,main线程结束了,守护线程Thread-0也结束了。
文章来源:https://uudwc.com/A/k6bz