多线程一些简单的基础

一、进程:进程是受操作系统管理的基本运行单位;

二、线程:在进程中独立运行的子任务;

三、多线程的好处:

可以在同一时间内运行更多不同种类的任务;

单任务的特点是排队执行,也就是同步,CPU利用率很低;

多任务的特点也就是多线程,同时执行,异步操作,CPU快速切换,提高利用率;

四、Java里面的多线程基础

1、实现多线程的两种方式,继承Thread类,实现Runnable接口,一般最好实现Runnable接口,因为Java是单继承机制,如果继承Thread类,就不能继承其他类,会给程序带来很大的不便;

注意:Thead类是实现了Ruannale接口的,它们是多态关系;

2、非线程安全

主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流程。

3、停止线程

在Java中有以下3种方法可以终止正在运行的线程:

(1)使用退出标志,使线程正常退出,也就是当run方法完成后线程终止;

(2)使用stop方法强行退出,但是已经过时,线程不安全,不建议使用;

(3)使用interrupt方法中断线程;

4、interrpt方法中断线程

调用interrupt方法仅仅是在当前线程中打了一个停止的标记,并不是真的马上停止线程;

(1)Thread.interrupted()方法是一个静态的方法,代表测试当前线程是否已经中断,中断状态返回true,注意当此方法连续执行两次时,第二次会返回false;因为该方法具有将状态标志清除为false的功能;

(2)this.isInterrupted()方法是一个非静态的方法,由线程的对象调用,判断该线程是否已经是中断状态,不具有清除状态的功能,也就是无论调用多少次,返回的结果一样;

 1 package concurrent;
 2
 3 class MyThread1 extends Thread {
 4     public void run() {
 5         try {
 6             for (int i = 0; i < 500000; i++) {
 7                 if (this.isInterrupted()) {
 8                     System.out.println("本线程被中断了:马上退出");
 9                     throw new InterruptedException();
10                 }
11                 System.out.println("i=" + (i + 1));
12             }
13             System.out.println("for循环外的,线程继续运行,并没有立即被中断!");
14         } catch (InterruptedException e) {
15             System.out.println("线程被中断后,如果有catch会进入异常处理,之后就不会继续往下运行!");
16             e.printStackTrace();
17         }
18     }
19 }
20 public class Testinterrupted {
21     public static void main(String[] args) {
22         try {
23             MyThread1 thread = new MyThread1();
24             thread.start();
25             System.out.println(Thread.currentThread().getName());
26             Thread.sleep(1000);// 把主线程停1秒
27             // thread.interrupt();//中断当前线程操作
28             Thread.currentThread().interrupt();// 中断当前线程操作
29             System.out.println("测试当前线程是否已经停止1:" + Thread.interrupted());
30             System.out.println("测试当前线程是否已经停止2:" + Thread.interrupted());
31             thread.interrupt();
32             System.out.println("测试指定对象线程是否已经停止1:" + thread.isInterrupted());
33             System.out.println("测试指定对象线程是否已经停止2:" + thread.isInterrupted());
34         } catch (InterruptedException e) {
35             e.printStackTrace();
36         }
37         System.out.println("end!");
38     }
39 }

5、停止线程的方法---异常法

相当于在if判断里面加一个抛出异常,之后在catch里面捕获,利用异常退出线程;

此外还可以直接用return来结束线程,不过还是建议用向上抛出异常来实现线程的停止,使线程停止事件得到传播;

6、stop强制停止线程的不良后果

强制让线程停止可能是一些清理性的工作得不到完成,另外就是对锁定的对象进行了“解锁”,导致数据得不到同步的处理,出现数据不一致的问题。

7、yield方法

Thread.yield()放弃当前的CPU资源的执行权,将它让给其他的任务去占用CPU的执行时间,时间不确定,可能又马上获取到了执行权继续执行;

8、线程的优先级

Java中将线程的优先级分为10个等级,分别是1-10,但是并没有强制对应操作系统中相对应的线程级别,只是大致对应;默认优先级为5,main主线程优先级为5

使用setPriority()设置线程的优先级,getPiority()获取线程的优先级,注意线程的优先级JDK是使用常量来预先设定的,1对于最小,10对应最大;但是并不是越大就越先执行,优先级越高,只是获取CPU切换时间片的几率越大,优先执行的概率较高而已;

 1 package concurrent;
 2
 3 class ThreadA extends Thread {
 4     private int count = 0;
 5     public int getCount(){
 6         return count;
 7     }
 8     public void run() {
 9         try {
10             for (int i = 0; i < 1000000; i++) {
11                 count = i;
12                 System.out.println(this.getName()+"-------->"+count);
13                 if (count >= 5000) {
14                     throw new InterruptedException();
15                 }
16             }
17         } catch (InterruptedException e) {
18             System.out.println(this.getName() + " 线程已经执行完毕!");
19         }
20     }
21 }
22
23 class ThreadB extends Thread {
24     private int count = 0;
25     public int getCount(){
26         return count;
27     }
28     public void run() {
29         try {
30             for (int i = 0; i < 1000000; i++) {
31                 count = i;
32                 System.out.println(this.getName()+"-->"+count);
33                 if (count >= 5000) {
34                     throw new InterruptedException();
35                 }
36             }
37         } catch (InterruptedException e) {
38             System.out.println(this.getName() + " 线程已经执行完毕!");
39         }
40     }
41 }
42
43 class MyThread2 extends Thread {
44
45     public void run() {
46         long beginTime = System.currentTimeMillis();
47         int count = 0;
48         for (int i = 0; i < 10000000; i++) {
49             // Thread.yield();
50             // 放弃当前的CPU资源的执行权,将它让给其他的任务去占用CPU的执行时间,时间不确定,可能又马上获取到了执行权继续执行;
51             count = count + (i + 1) * 2 / 2;
52         }
53         long endTime = System.currentTimeMillis();
54         System.out.println(this.getName() + "--"
55                 + Thread.currentThread().getPriority());
56         System.out.println(this.getPriority());
57         System.out.println(endTime - beginTime);
58     }
59 }
60
61 public class TestYield {
62     public static void main(String[] args) {
63         // MyThread2 m = new MyThread2();
64         // m.start();
65         // System.out.println(Thread.currentThread().getName());
66         // System.out.println(Thread.currentThread().getPriority());
67
68         try {
69             ThreadA a = new ThreadA();
70             ThreadB b = new ThreadB();
71             a.setPriority(Thread.MAX_PRIORITY);
72             b.setPriority(Thread.NORM_PRIORITY - 2);
73             a.start();
74             b.start();
75             Thread.sleep(20000);
76         } catch (InterruptedException e) {
77             e.printStackTrace();
78         }
79     }
80 }

9、守护线程

Java线程中有两种线程,一种是普通的用户线程,另一种是守护线程;

守护线程顾名思义就是守护普通线程的线程,它随着普通线程而生,随普通线程停止后自动销毁,守护线程不能独立存在,典型的守护线程就是JVM的GC线程,作用是为其他线程的运行提供便利服务;

 1 package concurrent;
 2
 3 class ThreadDaemon extends Thread {
 4     private int i = 0;
 5     public void run() {
 6         try {
 7             while (true) {
 8                 i++;
 9                 System.out.println(this.getName() + "-->" + i);
10                 Thread.sleep(1000);
11                 /*设置为守护线程后,线程sleep后会自动停止,这样可以当作一种线程停止的手段*/
12             }
13         } catch (InterruptedException e) {
14             e.printStackTrace();
15         }
16     }
17 }
18 public class TestDaemon {
19     public static void main(String[] args) {
20         try {
21             ThreadDaemon td = new ThreadDaemon();
22             td.setDaemon(true);
23             td.start();
24             Thread.sleep(1000);
25             System.out.println("线程td先设置为守护线程,运行后sleep后即停止了!");
26         } catch (InterruptedException e) {
27             e.printStackTrace();
28         }
29     }
30 }
时间: 2024-10-01 09:37:35

多线程一些简单的基础的相关文章

c#多线程(一)——基础概念和基本使用

一.多线程相关的基本概念 进程(Process):是系统中的一个基本概念. 一个正在运行的应用程序在操作系统中被视为一个进程,包含着一个运行程序所需要的资源,进程可以包括一个或多个线程 .进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的.进程可以理解为一个程序的基本边界. 线程(Thread):是 进程中的基本执行单元,是操作系统分配CPU时间的基本单位 ,在进

gdb调试多线程的简单命令

由于平时的编程当中经常会用到多线程,我想接触过多线程编程的人应该都会清楚多线程如果出了错,调起bug来是有多么麻烦,应为你某个地方出错了,有可能并不是这里的问题而是线程执行到这就切换到其他线程,而出错的是其他线程,我以前使用的办法是给某个线程sleep然后让内核自己调度去执行其他线程.很明显这种方法当有很多线程是并不是很使用,所以我就翻书学了几条调试多线程的简单gdb命令 1.测试所用的代码 1void *thread1(void *arg) 2{ 3 printf("New thread1\n

ruby简单的基础

好久没写记录东西了,最近决定记录写ruby方面的东西,大家一起学习. ruby 基础语法 1.注释 单行注释 ##开始到行末是单行注释 多行注释 =begin =end多行注释以=begin开始 以=end结束,=begin和=end前不能有其他字符,包括空格.一般=begin 和 =end独占一行,这样看起来比较清晰. Ruby中用;来表示一个语句结束.如果一行有多个语句,每个语句可以用:隔开,最后一个:可以省略. 换行表示一行结束,如果语句太长的话,我们可以用\连接下一行,表示这行还没有结束

ruby简单的基础 2

1.代码块 代码块是用大括号或者do...end括起来的一系列代码.{ #this is a block} do #this is a blockend [1,2,3,4,5].each {|i| puts i} [1,2,3,4,5].each do |i|puts iend这2中写法效果是一样的,用{}可能更像C的风格 2.作用域 Ruby程序只会在3个地方关闭前一个作用域,同时打开一个新的作用域: 类定义, class - end模块定义, module - end方法定义, def -

Java多线程之简单的线程同步实例

数据类: package Thread.MyCommon; public class Data { public int num = 0; public synchronized int getEven() { ++num; Thread.yield();//让另外线程先执行,加大测试效果几率 ++num; return num; } } 线程类: package Thread.MyCommon; public class myThread implements Runnable { priva

JAVA学习第六十课 — UDP协议 &amp;基于多线程模拟简单的QQ聊天程序

UDP传输 UDP有发送端和接受端,有两大类,DatagramSocket.DatagramPacket 建立发送端和接收端 建立数据包 调用Socket的接收发送方法 关闭Socket 注意:发送端和接收端是两个独立的运行程序 UDP发送端演示 DatagramPacket(byte[] buf, int length, InetAddress address, int port) 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号. public static voi

ruby简单的基础 5

方法和代码块 在Ruby中,{}或do...end之间的代码是一个代码块.代码块只能出现在一个方法的后边,它紧接在方法最后一个参数的同一行上,一般由yield关键字调用代码块中的代码. 方法是一个有名的代码块,是与一个或者多个对象相关联的参数化代码.调用方法时必须要给出方法名.所在对象(接受者),以及零个或者多个参数值,方法中最后一个表达式的值将作为方法调用的返回值. 代码块不是ruby可操作的对象,一般我们用一个Proc对象代表一个代码块.有两种方式的Proc对象,一种是proc,一种是lam

ruby简单的基础 3

类 Ruby中一切都是对象,包括一个常数.比如可以用.class属性来查看一个对象的类型,你可以看下1.class,会发现常数1的类型是Fixnum,1不过是Fixnum的一个实例. Ruby中的类以class开始 以end结束,类名首字母的约定是大写.Ruby中的方法以def开始 以end结束,方法名首字母的约定是小写.Ruby中的局部变量名首字母的约定是小写.Ruby中的构造函数名称为initialize.Ruby中的成员变量(实例变量)前导@符,在initialize里进行声明与初始化.R

Java 多线程IO简单实用Demo

多线程主要作用是充分利用Cpu,而不在于它的乱序性.本Demo不讲它竞争什么的.之前看过乱序打印ABC的例子什么的,那些有意义吗? 本Demo 是多线程打印文件夹下的文件,主要实现是用数组存放文件,一个游标遍历. 我们需要考虑在什么时候加互斥访问,本例用synchronized . 先考虑单线程的流程:客户端启动-->读取文件下的文件放到数组(IO)--> 取游标打印 ,游标加1 -- > 改文件写文件(IO) -- 重复上两步至越界 -- 结束 多线程时显然需要在"取游标打印