1.一个进程可以理解为一个应用程序,一个进程通常包括多个线程。进程可以理解为一个公司,线程理解为公司的员工。
2.进程A与进程B之间内存独立不共享线程A与线程B之间堆与方法区内存共享,但是栈是独立的,一个线程拥有一个栈!!!
3.单核cpu不能实现真正的多线程并发,但是可以“模拟多线程并发”,例如它可以使多个线程来回切换,这样一来给人的感觉像是并发的。
4.start方法会启动另一个分支线程,而run方法不会。
两种方式:
package com.javastudy.example11;
/*
1.一个进程可以理解为一个应用程序,一个进程通常包括多个线程。
进程可以理解为一个公司,线程理解为公司的员工:
2.进程A与进程B之间内存独立不共享
线程A与线程B之间堆与方法区内存共享,但是栈是独立的,一个线程拥有一个栈!!!
3.单核cpu不能实现真正的多线程并发,但是可以“模拟多线程并发”,例如它可以使多个线程来回切换,
这样一来给人的感觉像是并发的。
4.start方法会启动另一个分支线程,而run方法不会。
*/
public class Thread01 extends Thread{
public static void main(String[] args) {
//主线程
//方法一(继承Thread)
MyThread thread = new MyThread();
//启动另一个线程
thread.start();
for(int i=0;i<100;i++){
System.out.println("线程一执行"+i);
}
//方法二(实现Runable接口)
System.out.println("======方法二=============");
MyRun myrun=new MyRun();
Thread t=new Thread(myrun);
t.start();
for(int i=0;i<100;i++){
System.out.println("线程一执行"+i);
}
}
}
class MyThread extends Thread{
//分支线程
public void run(){
for(int i=0;i<100;i++){
System.out.println("线程二执行"+i);
}
}
}
//方法二 面向接口编程,常用
class MyRun implements Runnable{
@Override
public void run() {
for(int i=0;i<100;i++){
System.out.println("线程二执行"+i);
}
}
}
获取线程名字,修改名字,获取对象:
package com.javastudy.example11;
public class Thread02 {
public static void main(String[] args) {
Thread t=new Thread(new MyRun02());
t.start();
//获取名字
System.out.println("t1线程初始名字为-------"+t.getName());
for(int i=0;i<10;i++){
if(i==1){
//设置名字
t.setName("t1线程名字已被修改");
}
System.out.println(t.getName()+"-----"+i);
}
Thread t2=new Thread(new MyRun02());
//获取名字
System.out.println("t2线程初始名字为-------"+t2.getName());
//获取当前对象
System.out.println("将t2赋值为当前对象,即main");
t2=Thread.currentThread();
System.out.println("此时,t2线程名字为-------"+t2.getName());
MyThread02 myt=new MyThread02();
myt.start();
MyThread02 myt2=new MyThread02();
myt2.start();
}
}
class MyRun02 implements Runnable{
@Override
public void run() {
System.out.println("=================线程2启动=====================");
System.out.println("当前线程为");
}
}
class MyThread02 extends Thread{
public void run(){
Thread x1=Thread.currentThread();
System.out.println("当前线程为"+x1.getName());
x1.setName("change");
System.out.println("修改后为"+x1.getName());
/* for(int i=0;i<100;i++){
System.out.println("当前线程对象名字为"+i);
}*/
}
}
线程的休眠与唤醒
package com.javastudy.example11;
public class Thread03 {
public static void main(String[] args) {
MyRun03 myRun03 = new MyRun03();
Thread t=new Thread(myRun03);
t.start();
System.out.println("------主线程休眠3s-------");
try {
t.sleep(1000*3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------主线程休眠自动结束-------");
// System.out.println("强制分支休眠结束,通过异常机制interrupt");
// 方式一 t.interrupt();
// 方式二 t.stop();
//合理方式
myRun03.flag=false;
}
}
class MyRun03 implements Runnable{
boolean flag=true;
@Override
public void run() { //只能使用try catch,子类只能抛出更少的异常
System.out.println("------分支线程休眠5s-------");
if(flag){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------分支线程休眠结束-------");
}}
}
休眠-唤醒 运行截图