18.4 操作线程的方法

一、线程的休眠

  一种控制线程行为的方法使调用sleep()方法,sleep()方法需要一个参数用于指定该线程休眠的时间,该时间以毫秒为单位
  sleep()方法的语法如下:
    try{
      Thread.sleep(2000);
    }catch(InterruptedException e){
      e.printStackTrace();
    }
  上述代码会使线程在2秒之内不会进入就绪状态。由于sleep()方法的执行有可能抛出InterruptedException异常,所以将sleep()方法的调用放在try-catch块中。虽然使用sleep()方法的线程在一段时间内会醒来,但是并不能保证它醒来后进入运行状态,只能保证它进入就绪状态。

 1 package com.lzw;
 2
 3 import java.awt.*;
 4 import java.util.*;
 5
 6 import javax.swing.*;
 7 public class SleepMethodTest extends JFrame {
 8     /**
 9      *
10      */
11     private static final long serialVersionUID = 1L;
12     private Thread t;
13     // 定义颜色数组
14     private static Color[] color = { Color.BLACK, Color.BLUE, Color.CYAN,
15             Color.GREEN, Color.ORANGE, Color.YELLOW, Color.RED,
16             Color.PINK, Color.LIGHT_GRAY };
17     private static final Random rand = new Random();// 创建随机对象
18
19     private static Color getC() {// 获取随机颜色值的方法
20         return color[rand.nextInt(color.length)];
21     }
22
23     public SleepMethodTest() {
24         t = new Thread(new Runnable() {// 创建匿名线程对象
25             int x = 30;// 定义初始坐标
26             int y = 50;
27
28             public void run() {// 覆盖线程接口方法
29                 while (true) {// 无限循环
30                     try {
31                         Thread.sleep(100);// 线程休眠0.1秒
32                     } catch (InterruptedException e) {
33                         e.printStackTrace();
34                     }
35                     // 获取组件绘图上下文对象
36                     Graphics graphics = getGraphics();
37                     graphics.setColor(getC());// 设置绘图颜色
38                     // 绘制直线并递增垂直坐标
39                     graphics.drawLine(x, y, 100, y++);
40                     if (y >= 80) {
41                         y = 50;
42                     }
43                 }
44             }
45         });
46         t.start();// 启动线程/
47     }
48
49     public static void main(String[] args) {
50         init(new SleepMethodTest(), 100, 100);
51     }
52     // 初始化程序界面的方法
53     public static void init(JFrame frame, int width, int height) {
54         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
55         frame.setSize(width, height);
56         frame.setVisible(true);
57     }
58 }

二、线程的加入

  如果当前某程序为多线程序,加入存在一个线程A,现在需要插入线程B,并要求线程B先执行完毕,然后再继续执行线程A,此时可以使用Thread类中的join()方法来完成。
  当某个线程使用join()方法加入到另一个线程时,另一个线程会等待该线程执行完毕后再继续执行。

 1 package com.lzw;
 2
 3 import java.awt.*;
 4 import javax.swing.*;
 5
 6 public class JoinTest extends JFrame {
 7     /**
 8      *
 9      */
10     private static final long serialVersionUID = 1L;
11     private Thread threadA; // 定义两个线程
12     private Thread threadB;
13     final JProgressBar progressBar = new JProgressBar(); // 定义两个进度条组件
14     final JProgressBar progressBar2 = new JProgressBar();
15     int count = 0;
16
17     public static void main(String[] args) {
18         init(new JoinTest(), 100, 100);
19     }
20
21     public JoinTest() {
22         super();
23         // 将进度条设置在窗体最北面
24         getContentPane().add(progressBar, BorderLayout.NORTH);
25         // 将进度条设置在窗体最南面
26         getContentPane().add(progressBar2, BorderLayout.SOUTH);
27         progressBar.setStringPainted(true); // 设置进度条显示数字字符
28         progressBar2.setStringPainted(true);
29         // 使用匿名内部类形式初始化Thread实例子
30         threadA = new Thread(new Runnable() {
31             int count = 0;
32
33             public void run() { // 重写run()方法
34                 while (true) {
35                     progressBar.setValue(++count); // 设置进度条的当前值
36                     try {
37                         Thread.sleep(100); // 使线程A休眠100毫秒
38                         threadB.join(); // 使线程B调用join()方法
39                     } catch (Exception e) {
40                         e.printStackTrace();
41                     }
42                 }
43             }
44         });
45         threadA.start(); // 启动线程A
46         threadB = new Thread(new Runnable() {
47             int count = 0;
48
49             public void run() {
50                 while (true) {
51                     progressBar2.setValue(++count); // 设置进度条的当前值
52                     try {
53                         Thread.sleep(100); // 使线程B休眠100毫秒
54                     } catch (Exception e) {
55                         e.printStackTrace();
56                     }
57                     if (count == 100) // 当count变量增长为100时
58                         break; // 跳出循环
59                 }
60             }
61         });
62         threadB.start(); // 启动线程B
63     }
64
65     // 设置窗体各种属性方法
66     public static void init(JFrame frame, int width, int height) {
67         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
68         frame.setSize(width, height);
69         frame.setVisible(true);
70     }
71 }

三、线程的中断

  以往有的时候回使用stop()方法停止线程,但当前版本的JDK早已废除了stop()方法,不建议使用stop()方法来停止一个线程的运行。现在提倡在run()方法中使用无线循环的形式,然后使用一个布尔型标记控制循环的停止。
  如果线程因为使用了sleeo()方法或wait()方法进入了就绪状态,可以使用Thread类中的interrupt()方法时线程离开run()方法,同时结束线程,但程序会抛出InterruptedException异常,用户可以在处理该异常时完成线程的中断业务处理,如终止while循环。

 1 package com.lzw;
 2
 3 public class InterruptedTest implements Runnable{
 4     private boolean isContinue = false;    //设置一个编辑变量,默认值为false
 5
 6     public void run() {
 7         while(true) {
 8             //...
 9             if(isContinue)    //当isContinue变量为true时,停止线程
10                 break;
11         }
12     }
13
14     public void setContinue() {
15         this.isContinue = true;    //定义设置isContinue变量为true的方法
16     }
17 }

 1 package com.lzw;
 2
 3 import java.awt.*;
 4 import javax.swing.*;
 5
 6 public class InterruptedSwing extends JFrame {
 7     /**
 8      *
 9      */
10     private static final long serialVersionUID = 1L;
11     Thread thread;
12
13     public static void main(String[] args) {
14         init(new InterruptedSwing(), 100, 100);
15     }
16
17     public InterruptedSwing() {
18         super();
19         final JProgressBar progressBar = new JProgressBar(); // 创建进度条
20         // 将进度条放置在窗体合适位置
21         getContentPane().add(progressBar, BorderLayout.NORTH);
22         progressBar.setStringPainted(true); // 设置进度条上显示数字
23         thread = new Thread(new Runnable() {
24             int count = 0;
25
26             public void run() {
27                 while (true) {
28                     progressBar.setValue(++count); // 设置进度条的当前值
29                     try {
30                         Thread.sleep(1000); // 使线程休眠1000豪秒
31                         // 捕捉InterruptedException异常
32                     } catch (InterruptedException e) {
33                         System.out.println("当前线程序被中断");
34                         break;
35                     }
36                 }
37             }
38         });
39         thread.start(); // 启动线程
40         thread.interrupt(); // 中断线程
41     }
42
43     public static void init(JFrame frame, int width, int height) {
44         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
45         frame.setSize(width, height);
46         frame.setVisible(true);
47     }
48
49 }

四、线程的礼让

  Thread类中提供了一种礼让方法,使用yield()方法表示,它只是给当前正处于运行状态的线程一个提醒,告知它可以将资源礼让给其它线程,但这仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。
  yield()方法使具有同样优先级的线程有进入可执行状态的机会,当当前线程放弃执行权时会再度回到就绪状态。对于支持多任务的操作系统来说,不需要调用yield()方法,因为操作系统会为线程自动分配CPU时间片来执行。

原文地址:https://www.cnblogs.com/studycode/p/9581437.html

时间: 2024-08-28 01:33:21

18.4 操作线程的方法的相关文章

android操作线程各种方法解析

(一)刚开始学习android的时候我是这么写的 1 new Thread( new Runnable() { public void run() { myView.invalidate(); } }).start(); 后来看到别的博客说这种违反android单线程模型 本人不理解非要刨根问题 那么它是怎么违反单线程模型的呢? 百度了一下找到了原因 如下 一个 Android 程序开始运行时,就有一个主线程Main Thread被创建.该线程主要负责UI界面的显示.更新和控件交互,所以又叫UI

java创建线程的方法

1.1      创建线程 1.1.1     无返回值的线程创建 package com.first; public class ThreadTest { public static void main(String[] args)  { System.out.println("主线程ID:"+Thread.currentThread().getId()); MyThread thread1 = new MyThread("thread1");//(1)继承thr

线程间操作无效: 从不是创建控件“控件id”的线程访问它。(.net跨线程执行方法)

找了好久资料,终于解决了,特此记录下来. 1 delegate void DelListHandler(string number); /// <summary> /// 按标识删除listview内容 /// </summary> /// <param name="number">标识</param> private void DelListViewLog(string number) { for (int i = 0; i <

C#用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程

C#用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程C# 2011-03-05 13:06:24 阅读19 评论0   字号:大中小 订阅 用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程 在C#中使用线程的方法很多,使用委托的BeginInvoke和EndInvoke方法就是其中之一. BeginInvoke方法可以使用线程异步地执行委托所指向的方法.然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回

封装JDBC操作数据库的方法

自己动手封装java操作数据库的方法: 一:目录结构 二:所需依赖的第三方jar包 这里只需引入mysql-connector-java-5.1.8-bin.jar,mysql数据库驱动jar包 三:代码 1:和数据库进行交互,首先是数据源,获取连接,代码如下: 1 /** 2 * 3 */ 4 package com.hlcui.datasource; 5 6 import java.sql.Connection; 7 import java.sql.DriverManager; 8 impo

多线程之间的通信(等待唤醒机制、Lock 及其它线程的方法)

一.多线程之间的通信. 就是多个线程在操作同一份数据, 但是操作的方法不同. 如: 对于同一个存储块,其中有两个存储位:name   sex, 现有两个线程,一个向其中存放数据,一个打印其中的数据. 为了解决上述问题中的安全问题(在存放线程进行存放操作的时候, 打印线程不能对共有数据进行操作),所以应当对两个线程       操作共有数据的代码部分进行同步(使用synchronized(),来进行同步, 注意 :使用同一个对象作为同步锁. 二.等待唤醒机制. 在上述案例实现过后运行,会发现:打印

Qt新建线程的方法(四种办法,很详细,有截图)

看了不少Qt线程的东西,下面总结一下Qt新建一个线程的方法. 一.继承QThread 继承QThread,这应该是最常用的方法了.我们可以通过重写虚函数void QThread::run ()实现我们自己想做的操作,实现新建线程的目的.前面已经介绍了Qthread,这里就不重复了. 这种方法,我们每一次要新建一个线程都需要继承Qthread,实现一个新的类,有点不太方便.但是相对于Qrunnable,这种方法的好处就是我们可以直接调用对象的start()函数启动线程,而Qrunnable必须借助

Java并发学习之四——操作线程的中断机制

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.如果线程实现的是由复杂算法分成的一些方法,或者他的方法有递归调用,那么我们可以用更好的机制来控制线程中断.为了这个Java提供了InterruptedException异常.当你检测到程序的中断并在run()方法内捕获,你可以抛这个异常. 2.InterruptedException异常是由一些与并发API相关的Java方法,如sleep()抛出的. 下面以程序解释 package chapter; import java.io.File

IOS:FMDB使用databaseQueue实现数据库操作线程安全

sqlite数据库是ios开发中经常使用到的数据持久化方案,因为项目需求的不同,对数据库操作的要求也不同. 由于最近使用sqlite时,有一些地方需要频繁的更新,这时在多线程操作时,其他线程访问数据库会造成程序崩溃,因为之前的框架里设计的数据库管理工具类采用的是单例模式,这样在多线程操作同一个数据库时很容易引起冲突,导致程序崩溃,所以开始寻找多线程下线程安全的办法. 其实FMDB本身已经对多线程做了考虑,FMDatabaseQueue就是为了解决数据库操作线程安全的,只是由于之前框架集成的单例操