IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

线程

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

一、线程的概念

进程是正在执行的程序。在操作系统中进程是进行系统资源分配、调度和管理的最小单位,进程在执行过程中拥有独立的内存单元。比如:Windows采用进程作为最小隔离单位,每个进程有属于自己的数据段、程序段 ,并且与别的进程没有任何关系。

一个或更多的线程构成了一个进程(操作系统是以进程为单位的,而进程是以线程为单位的,进程中必须有一个主线程)。

为了解决进程调度资源的浪费,为了能够共享资源,出现了线程。线程是CPU调度和分派的基本单位,它可与同属一个进程的其他的线程共享进程所拥有的全部资源,多个线程共享内存,从而极大地提高了程序的运行效率

如果一个进程没有了,那么线程肯定会消失,如果线程消失了,但是进程未必会消失。而且所有线程都是在进程的基础之上并同时运行。

二、创建线程的两种方式及区别

1 继承Thread类

1、1 示例代码

84_1.png 84_2.png

 package com.study.test;

 //创建线程的两种方式:继承Thread
 //必须明确的覆写Thread类中的run方法,此方法为线程的主体
 class AA extends Thread {
     public void run() {
         while (true) {
             System.out.println("world");
             try {
                 Thread.sleep(2000);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }
 }

 public class MyThread {
     // main函数为主线程,运行时先运行主线程,再运行其他线程
     public static void main(String[] args) throws InterruptedException {
         AA a1 = new AA();
         a1.start();// 必须先start线程,不能直接调用线程里面的函数,否则归属为主线程
         while (true) {
             System.out.println("hello");
             Thread.sleep(2000);// 让线程等待2s,先让其他进程运行,2s后再运行
         }
     }

 }

View Code

2 实现Runnable接口

2、1 定义一个类,实现Runnable接口,并覆盖 run()方法,在这个方法里是我们希望这个线程运行的代码。

2、2 创建一个这个新类的对象。

2、3 创建一个Thread类的对象,用刚才的Runnable对象作为构造函数参数。

2、4 调用Thread对象的start()方法来启动线程。

2、5 示例代码

84_3.png 84_4.png

 package com.study.test;

 //创建线程的两种方式:实现Runnable接口
 //必须明确的覆写Thread类中的run方法,此方法为线程的主体

 class AA implements Runnable {
     public void run() {
         while (true) {
             System.out.println("world");
             try {
                 Thread.sleep(2000);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
     }
 }

 public class MyThread {
     // main函数为主线程,运行时先运行主线程,再运行其他线程
     public static void main(String[] args) throws InterruptedException {
         AA a1 = new AA();// 创建一个这个新类的对象。

         Thread t1 = new Thread(a1);// 创建一个Thread类的对象,用刚才的Runnable对象作为构造函数参数。

         t1.start();// 必须先start线程,不能直接调用线程里面的函数,否则归属为主线程
         while (true) {
             System.out.println("hello");
             Thread.sleep(2000);// 让线程等待2s,先让其他进程运行,2s后再运行
         }
     }

 }

View Code

3、实现Runnable接口与继承Thread的区别

3、1 实现Runnable 接口比继承 Thread 类有如下的明显优点:
(1)、适合多个相同程序代码的线程去处理同一个资源。
(2)、可以避免由于单继承局限所带来的影响。
(3)、增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。

3、2 Thread更加简单易用

三、线程的生命周期

多线程在操作过程也有一个固定的操作状态,任何一个线程都具有五种状态:创建、就绪、运行、阻塞、终止

创建状态:准备好的一个多线程的对象

就绪状态:调用了start()方法,等待cpu调度

运行状态:执行run()方法。

阻塞状态:暂停线程,可以将资源交给其他资源使用

终止状态:线程执行完毕,不再使用。

四、线程同步加锁解决资源竟态问题

1、 竞态的概念

1、1 多个线程调用同一资源就会产生竞争状态(竞态)

1、2 访问的同一资源,我们称之为临界资源

1、3 访问临界资源的代码,我们称之为临界区

1、4 如果两个线程同时取得数据,将会造成流水号重复

1、5 示例代码

84_5.png 84_6.png

 class CThread extends Thread
 {
     public static int i=1; //相当于全局变量    临界资源
     //临界区
     public void run()
     {
         while(true)
         {
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }//模拟做一些事情
             out.println(CThread.i);//取得数据
             try {
                 Thread.sleep(1000);
             } catch (InterruptedException e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
             CThread.i++;//流水号加1
             if (CThread.i==100) break;
         }
     }
 }
 public class Hello1 {
     public static void main(String[] args) throws InterruptedException {
         //多个线程(t1,t2)同时访问全局变量i;
         Thread t1=new CThread();
         t1.start();
         Thread t2=new CThread();
         t2.start();

     }
 }

View Code

2、 解决方法是利用同步加锁

2、1 多个线程访问同一资源,线程之间相互协调的功能,叫线程同步。也就是说在同一个时间段内只能有一个线程进行,其他线程要等待此线程完毕之后才可以继续执行。

2、2 在临界资源上放置同步块synchronized()可以解决这个问题

2、3 线程执行到synchronized()代码块时首先看看有没有锁定,如果没有锁定,则获得锁,如果已经锁定,则需要等待,线程离开synchronized()代码块的时候释放锁。

2、4 这一切的过程由系统任意给定的一个对象来监视,这个对象放入synchronized块的()中

2、5 示例代码

84_7.png 84_8.png

 package com.study.test;

 import static java.lang.System.*;

 //利用同步加锁的方式解决竟态(多个线程竟争同一资源)问题
 class CThread extends Thread {
     public static int i = 1; // 相当于全局变量
     public static Object j = new Object();// 随便一个对象用于监视

     public void run() {
         while (true) {
             synchronized (j) // 对对象加锁,这里用的是任意一个对象,当一个对象进来的时候看有没有对象正在使用,如果有就等待,没有的话就使用并加锁,使用完以后进行解锁
             { // 对临界区加锁实现同步
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 } // 模拟做一些事情
                 out.println(CThread.i);// 取得数据
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
                     e.printStackTrace();
                 }
                 CThread.i++;// 流水好加1
                 if (CThread.i == 100)
                     break;
             } // 解锁
         }
     }
 }

 public class MyThread {
     public static void main(String[] args) throws InterruptedException {
         Thread t1 = new CThread();
         t1.start();
         Thread t2 = new CThread();
         t2.start();

     }
 }

View Code

五、线程安全类

1 把一个类中的方法标志为synchronized,我们称之为该类线程安全,多个线程访问同一个对象的内部数据将会采用线程同步

84_9.png 84_10.png

 package com.study.test;

 import static java.lang.System.out;

 //把一个类中的方法标志为synchronized,我们称之为该类线程安全,多个线程访问同一个对象的内部数据将会采用线程同步
 class dd// 线程安全类
 {
     public int i = 1;

     public void run() {
         while (true) {
             synchronized (this) {
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 } // 模拟做一些事情
                 out.println(i);// 取得数据
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 i++;// 流水好加1
                 if (i == 100)
                     break;
             }
         }
     }
 }

 class CThread extends Thread {
     // public static int i=1; //相当于全局变量
     public static dd j = new dd();// 随便一个对象用于监视

     public void run() {
         j.run();
     }
 }

 public class MyThread {
     public static void main(String[] args) throws InterruptedException {

         Thread t1 = new CThread();
         t1.start();
         Thread t2 = new CThread();
         t2.start();

     }
 }

View Code

六、Notify()与notifyall()区别

1、 使用notify(),通知第一个等待线程,所有排队的线程按先后顺序执行。
2、 notifyall()通知所有的等待线程,那么优先级别高线程就先执行。

七、yeild()与sleep()的区别

1、 yield:发杨雷锋主义精神,主动暂停当前正在执行的线程对象,并执行其他线程。 将执行的权力交给其它线程,自己到队列的最后等待。

2、 Thread.yield()线程是从Running状态到Ready状态。

3、 Thread.sleep()调用会给较低优先级线程一个运行的机会。

4、 Thread.yield()方法只会给相同优先级线程一个执行的机会。

八、join()

在一个线程A里面加入另一个线程B运行,等待B线程运行完以后再运行A线程

九、wait notify 的应用生产者消费者问题

84_11.png 84_12.png

 package com.study.test;

 import static java.lang.System.in;
 import static java.lang.System.out;

 import java.io.IOException;
 import java.util.Scanner;

 class Product {
     public static Object monitor = new Object();// 监视
     public static String flowNo = null;// 流水号
 }

 class Customer extends Thread {
     Customer(String name) {
         super(name);
     }

     public void run() {
         // while(true)
         // {
         synchronized (Product.monitor) {
             out.println("now the thread:" + Thread.currentThread().getName() + " get lock");
             try {
                 out.println("now the thread:" + Thread.currentThread().getName() + " is waiting");
                 Product.monitor.wait(); // wait的同时会解开锁给其他线程
                 out.println(Product.flowNo);
             } catch (Exception e) {
                 out.println(e.getMessage());
             }
         }

         // }
     }
 }

 class Producter extends Thread {
     Producter(String name) {
         super(name);
     }

     public void run() {
         // while(true)
         // {
         synchronized (Product.monitor) {
             out.println("now the thread:" + Thread.currentThread().getName() + " get lock");
             // 生产产品
             Scanner sc = new Scanner(in);
             Product.flowNo = sc.nextLine();
             out.println("now notify all thread to work");
             Product.monitor.notifyAll();// 通知所有的线程开始运行
         }

         // }
     }
 }

 public class MyThread {
     public static void main(String[] args) throws InterruptedException, IOException {
         Customer t1 = new Customer("customer");
         t1.start();
         Producter p1 = new Producter("producter");
         p1.start();
     }
 }

View Code

十、线程池以及使用线程池的好处

1、多线程运行时间,系统不断的启动和关闭新线程,成本非常高
2、使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。

84_13.png 84_14.png

 package com.study.test;

 import static java.lang.System.out;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;

 class CThread extends Thread
 {
     public static int i=1; //相当于全局变量
     public static Object j=new Object();//随便一个对象用于监视
     public void run()
     {
         while(true)
         {
             synchronized(j) //对对象加锁,这里用的是任意一个对象
             { //对临界区加锁实现同步
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }//模拟做一些事情
                 out.println(CThread.i);//取得数据
                 try {
                     Thread.sleep(1000);
                 } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                 }
                 CThread.i++;//流水好加1
                 if (CThread.i==100) break;
             }//解锁
         }
     }
 }
 public class MyThread {
     public static void main(String[] args) throws InterruptedException {
 //        Thread t1=new CThread();
 //        t1.start();
 //        Thread t2=new CThread();
 //        t2.start();


 //现在不要用单个线程去跑,当然这个是服务器端一定干的事,最好使用线程池
 //使用线程池的好处:
 //        1、多线程运行时间,系统不断的启动和关闭新线程,成本非常高
 //        2、使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,
 //        线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。


 //        调用Executors类的静态工厂方法创建一个ExecutorService对象。
         ExecutorService server=Executors.newFixedThreadPool(2);//创建两个线程的池
 //        创建Runnable实现类,作为线程执行任务
 //        调用ExecutorService对象的submit方法来提交Runnable实例。
         server.submit(new CThread());//提交线程到线程池去处理
         server.submit(new CThread());
 //        当不想提交任何任务时调用ExecutorService对象的shutdown方法来关闭线程池。
         server.shutdown();//关闭线程池

     }
 }

View Code

十一、定时调度

1、 定时调度的本质是一个线程,只是系统控制了这个线程运行的时间与频率

84_15.png 84_16.png

 package com.study.test;

 import static java.lang.System.out;
 import static java.lang.System.in;

 import java.io.IOException;
 import java.util.Timer;
 import java.util.TimerTask;

 class aa extends TimerTask {

     @Override
     public void run() {
         out.println("1 ");
         // 定时调度的本质是一个线程,只是系统控制了这个线程运行的时间与频率
         out.println(Thread.currentThread().getName());
     }

 }

 public class MyTimer {
     public static void main(String[] args) throws InterruptedException, IOException {

         Timer t1 = new Timer();
         t1.schedule(new aa(), 0, 1000); // 利用cpu的时钟去控制的
         in.read();//输入任意一个值回车时种植执行调度
         t1.cancel();//表示终止定时器

     }

 }

View Code

2、 schedule到达某一个时间点开始执行

84_17.png 84_18.png

 package com.study.test;

 import static java.lang.System.out;
 import static java.lang.System.in;

 import java.io.IOException;
 import java.util.Calendar;
 import java.util.Timer;
 import java.util.TimerTask;

 class aa extends TimerTask {

     @Override
     public void run() {
         out.println("1 ");
         // 定时调度的本质是一个线程,只是系统控制了这个线程运行的时间与频率
         out.println(Thread.currentThread().getName());
     }

 }

 public class MyTimer {
     public static void main(String[] args) throws InterruptedException, IOException {

         Timer t1 = new Timer();
         aa aa1 = new aa();
         Calendar c1 = Calendar.getInstance();
         c1.add(Calendar.SECOND, 5);
         c1.set(2017, 10, 8, 00, 29, 10);
         t1.schedule(aa1, c1.getTime());// 到了某一个时间点开始执行

     }

 }

View Code

3、 到达某一个时间点,再按照频率执行

84_19.png 84_20.png

 package com.study.test;

 import static java.lang.System.out;
 import static java.lang.System.in;

 import java.io.IOException;
 import java.util.Calendar;
 import java.util.Timer;
 import java.util.TimerTask;

 class aa extends TimerTask {

     @Override
     public void run() {
         out.println("1 ");
         // 定时调度的本质是一个线程,只是系统控制了这个线程运行的时间与频率
         out.println(Thread.currentThread().getName());
     }

 }

 public class MyTimer {
     public static void main(String[] args) throws InterruptedException, IOException {

         Timer t1 = new Timer();
         aa aa1 = new aa();
         Calendar c1 = Calendar.getInstance();
         c1.add(Calendar.SECOND, 5);
         c1.set(2017, 10, 8, 00, 35, 00);
         // t1.schedule(aa1, c1.getTime());// 到了某一个时间点开始执行
         t1.schedule(aa1, c1.getTime(), 1000);// 到了某一个时间点开始,按照1秒的频率

     }

 }

View Code

4、 延误时间间隔之后执行

84_21.png 84_22.png

 package com.study.test;

 import static java.lang.System.out;
 import static java.lang.System.in;

 import java.io.IOException;
 import java.util.Calendar;
 import java.util.Timer;
 import java.util.TimerTask;

 class aa extends TimerTask {

     @Override
     public void run() {
         out.println("1 ");
         // 定时调度的本质是一个线程,只是系统控制了这个线程运行的时间与频率
         out.println(Thread.currentThread().getName());
     }

 }

 public class MyTimer {
     public static void main(String[] args) throws InterruptedException, IOException {

         Timer t1 = new Timer();
         aa aa1 = new aa();
         Calendar c1 = Calendar.getInstance();
         c1.add(Calendar.SECOND, 5);
         c1.set(2017, 10, 8, 00, 35, 00);
         // t1.schedule(aa1, c1.getTime());// 到了某一个时间点开始执行
         // t1.schedule(aa1, c1.getTime(), 1000);// 到了某一个时间点开始,按照1秒的频率
         t1.schedule(aa1, 2000, 1000);// 延误多少时间之后,按照1秒的频率

     }

 }

View Code

5、 固定频率

84_23.png 84_24.png

 package com.study.test;

 import static java.lang.System.out;
 import static java.lang.System.in;

 import java.io.IOException;
 import java.util.Calendar;
 import java.util.Timer;
 import java.util.TimerTask;

 class aa extends TimerTask {

     @Override
     public void run() {
         out.println("1 ");
         // 定时调度的本质是一个线程,只是系统控制了这个线程运行的时间与频率
         out.println(Thread.currentThread().getName());
     }

 }

 public class MyTimer {
     public static void main(String[] args) throws InterruptedException, IOException {

         Timer t1 = new Timer();
         aa aa1 = new aa();
         Calendar c1 = Calendar.getInstance();
         c1.add(Calendar.SECOND, 5);
         c1.set(2017, 10, 8, 00, 35, 00);
         // t1.schedule(aa1, c1.getTime());// 到了某一个时间点开始执行
         // t1.schedule(aa1, c1.getTime(), 1000);// 到了某一个时间点开始,按照1秒的频率
         // t1.schedule(aa1, 2000, 1000);// 延误多少时间之后,按照1秒的频率
         // t1.schedule(aa1,c1.getTime(),5000 );//过去的时间以当前时间为准,然后按照频率运行
         t1.scheduleAtFixedRate(aa1, c1.getTime(), 5000);// 一定要补足,以固定频率为准

     }

 }

View Code

6、 多定时器,多任务

84_25.png 84_26.png

 package com.study.test;

 import static java.lang.System.out;

 import java.io.IOException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Timer;
 import java.util.TimerTask;

 class aa extends TimerTask {

     @Override
     public void run() {
         out.println("1 ");
     }

 }

 class bb extends TimerTask {

     @Override
     public void run() {
         // TODO Auto-generated method stub
         out.println("2 ");
     }

 }

 class cc extends TimerTask {

     @Override
     public void run() {
         SimpleDateFormat sf = new SimpleDateFormat("yyy.MM.dd hh:mm:ss");
         String curDate = sf.format(new Date(this.scheduledExecutionTime()));
         out.println(curDate + "    3 ");
     }

 }

 public class MyTimer {
     public static void main(String[] args) throws InterruptedException, IOException {
         Timer t1 = new Timer();
         aa aa1 = new aa();
         bb bb1 = new bb();
         t1.scheduleAtFixedRate(aa1, 0, 2000);// 加入一个任务
         t1.scheduleAtFixedRate(bb1, 0, 1000);// 加入一个任务
         Timer t2 = new Timer();
         cc cc1 = new cc();
         t2.scheduleAtFixedRate(cc1, 0, 3000);// 另外一个定时器加入任务

     }

 }

View Code

文章永久链接:https://tech.souyunku.com/?p=14491


Warning: A non-numeric value encountered in /data/wangzhan/tech.souyunku.com.wp/wp-content/themes/dux/functions-theme.php on line 1154
赞(64) 打赏



未经允许不得转载:搜云库技术团队 » 线程

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码
IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

评论 抢沙发

大前端WP主题 更专业 更方便

联系我们联系我们

觉得文章有用就打赏一下文章作者

微信扫一扫打赏

微信扫一扫打赏


Fatal error: Uncaught Exception: Cache directory not writable. Comet Cache needs this directory please: `/data/wangzhan/tech.souyunku.com.wp/wp-content/cache/comet-cache/cache/https/tech-souyunku-com/index.q`. Set permissions to `755` or higher; `777` might be needed in some cases. in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php:367 Stack trace: #0 [internal function]: WebSharks\CometCache\Classes\AdvancedCache->outputBufferCallbackHandler() #1 /data/wangzhan/tech.souyunku.com.wp/wp-includes/functions.php(5109): ob_end_flush() #2 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(303): wp_ob_end_flush_all() #3 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters() #4 /data/wangzhan/tech.souyunku.com.wp/wp-includes/plugin.php(470): WP_Hook->do_action() #5 /data/wangzhan/tech.souyunku.com.wp/wp-includes/load.php(1097): do_action() #6 [internal function]: shutdown_action_hook() #7 {main} thrown in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php on line 367