2018.4.23
线程
多线程和多进程:
线程:
在一个软件中,负责不同功能的子程序,称之为线程。
进程:
是在计算机系统中所有正在运行的程序都可以看做是一个进程,多进程的操作系统。
计算机常识问题:
windows操作系统是一个多任务的操作系统,为什么windows可用同时执行多任务???
从表面上看:windows的确可以同时执行不同的应用程序,同时执行:eclipse 还有QQ 玩游戏,一些电脑管家类的软件,会提示你,关闭掉占用网络较多和内存占用较多的程序。 为什么?
降低CPU,内存,网络的使用率,给游戏提供更好的 运行环境。
从实际出发:
CPU其实是一个傻子,一次只能做一件事情,但是执行力很强。每一个CPU的内核在一个时间片内
只能执行一件事情。但是这个时间片非常的短,不同的程序会出现在不同的时间片上,不断地切换
所以感觉是在 同时运行,
现在的CPU基本上都是多核多线程的
面试题:
请问一个java程序在运行的时候,最少有几个线程???
最少是两个线程:1.main线程 2.JVM的垃圾回收机制。
多线程的好处:
1.可以让一个程序同时知悉不同的任务
2.可以提高资源的利用率
多线程的弊端:
1.线程安全问题 之前的迭代器。
2.增加了CPU负担
3.降低了其他程序CPU的执行概率
4.容易出现死锁行为。
如何创建一个线程
两种方式:
1.自定义一个类继承Thread类,那么这个类就可以看作是一个多线程类
2.要求【重写】Thread里面的run方法,吧需要执行的自定义线程代码放入run
class MyThread extends Thread{
//要求重写【run】方法
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("自定义Thread类" + i);
}
}
}
public class Demo1 {
public static void main(String[] args) {
//1.创建自定义线程类的类对象
MyThread myThread = new MyThread();
//2.启动线程,尝试调用run方法
//myThread.run();尝试调用run方法,相当于调用了一个普通的方法,而不是一个线程
myThread.start();//启动线程的方式,会发现,MyThread线程和main线程在抢占CPU资源
for (int i = 0; i < 10; i++) {
System.out.println("main线程"+i);
}
}
/*
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
//遍历第一种方式
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//遍历的第二种方式
for (String string : list) {
System.out.println(string);
}
//遍历的第三种方式
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
*/
}
结果:
main线程0
自定义Thread类0
main线程1
自定义Thread类1
自定义Thread类2
自定义Thread类3
自定义Thread类4
自定义Thread类5
自定义Thread类6
自定义Thread类7
自定义Thread类8
自定义Thread类9
main线程2
main线程3
main线程4
main线程5
main线程6
main线程7
main线程8
main线程9
线程实例
用线程同时
小芳视频和小红聊天
class VideoThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("和小芳视频中........");
}
}
}
class ChatThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
}
System.out.println("和小红聊天中........");
}
}
public class Demo1 {
@Test //注解
public void test1() {
VideoThread videoThread = new VideoThread();
ChatThread chatThread = new ChatThread();
videoThread.start();
chatThread.start();
}
}
线程常用方法
线程中的常用方法:
thread(String name);初始化线程名字,属于线程的一个有参数的构造方法。
setName(String name);修改线程的名字
getName();获取线程的名字。
static sleep();static静态方法,通过Thread类名调用,这里需要处理一些异常,要求当前线程睡觉多少毫秒。
【哪一个热线执行了sleep方法,哪一个线程就睡觉】
static currentThread();static静态方法,返回当前的线程对象
【哪一个线程执行了currentThread方法,就返回哪一个线程对象】
getPriority(); 返回当前线程的优先级CPU执行的优先级,不是绝对的。
setPriority(int newPriority); 设置线程的优先级。
【注意】
线程的优先级范围是1-10,10最高,1最低
这里的优先级只是提高了当前线程用于CPU执行权概率,并不能完全保证当前线程能够一定会占用更多的cpu时间片。
线程默认的优先级是5
37:Thread[main,5,main]
Thread[线程名,优先级,线程组名]
interface A {
public void testA();
}
public class Demo2 extends Thread implements A{
public Demo2(String name) {
super(name);
}
@Override
public void testA() {
//这里也无法抛出异常,两种处理方法,第一种,捕获异常,第二种,在接口声明方法部分,声明该异常。
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
//这里是Demo2线程对象的线程代码
System.out.println("27:"+Thread.currentThread());
for (int i = 0; i < 20; i++) {
System.out.println("自定义线程");
/*
在其他方法中,使用sleep方法,可以抛出可以捕获,但是在run方法中为什么只有捕获没有抛出??
这是一个语法规则:在java中,重写父类的方法,要求和父类的方法声明一模一样,在Thread类中】
run方法没有抛出异常,所以在子类中,你也不能抛出异常,要和父类一致。
*/
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
//这里是main线程。
Demo2 demo2= new Demo2("狗蛋");
//demo2.setName("狗娃");
demo2.setPriority(10);
demo2.start();//开启自定义线程,这里是自定义线程中的run方法里面的线程
System.out.println("37:"+Thread.currentThread());
for (int i = 0; i < 20; i++) {
System.out.println("这里是main线程");
sleep(10);
}
}
}