JAVA--浅谈线程
来源:互联网 发布:腾讯围棋 mac 编辑:程序博客网 时间:2024/06/05 22:24
写在前面:
以下均为楼主自己理解,请多指正!
- 线程简介
现在的操作系统是多任务操作系统。多线程是实现多任务的一种方式。
进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程中可以启动多个线程。比如在Windows系统中,一个运行的exe就是一个进程。
线程是指进程中的一个执行流程,一个进程中可以运行多个线程。比如java.exe进程中可以运行很多线程。线程总是属于某个进程,进程中的多个线程共享进程的内存。
“同时”执行是人的感觉,在线程之间实际上轮换执行。
线程的实现
1).通过继承Thread类实现线程
通过创建新的类继承Thread类,重写基类Thread中的run方法即可实现,在需要启动线程的地方,通过Thread中的Start()方法即可实现线程的启动。
代码实例:
/** * */package test线程;/** * @author 寒 * */public class TestThread extends Thread{ private String name; /** * @param string */ public TestThread(String string) { // TODO 自动生成的构造函数存根 this.name = string; } public void run(){ for(int i = 0; i < 10 ; i++){ System.out.println("第" + i + "次调用" + this.name + " " + this.getName()); } } /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 new TestThread(" 我是线程0 ").start(); new TestThread(" 我是线程1 ").start(); }}
2).通过实现Runnable接口实现线程
通过Thread thread = new Thread(new Runnable(){});来实现,Runnable接口内包含run()方法,只需在接口内实现该方法并启动即可实现线程。
代码实例:
/** * */package test线程;import java.awt.BorderLayout;import javax.swing.JFrame;import javax.swing.JProgressBar;/** * @author 寒 * */public class InterruptedSwing extends JFrame{ Thread thread; /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 init(new InterruptedSwing(), 300,300); } public InterruptedSwing(){ super(); final JProgressBar progressBar = new JProgressBar(); getContentPane().add(progressBar, BorderLayout.NORTH); progressBar.setStringPainted(true); thread = new Thread(new Runnable(){ int count = 0; @Override public void run() { // TODO 自动生成的方法存根 while(true){ progressBar.setValue( ++ count); try{ Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } } } }); thread.start(); thread.interrupt(); } public static void init(JFrame frame, int width , int height){ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(width, height); frame.setVisible(true); }}
线程的休眠
以下是线程的生命周期示意图,线程包含 出生、就绪、运行、等待、休眠、阻塞、死亡状态。其中线程的休眠使用sleep()方法是实现。使用了sleep()的线程会在一段时间后醒来,但是并不能保证线程醒来后即可进入运行状态,只能进入就绪状态。代码实例:
/** * */package test线程;import java.awt.Color;import java.awt.Graphics;import java.util.Random;import javax.swing.*;/** * @author 寒 * */public class SleepMethodTest extends JFrame{ private Thread t; private static Color []color = {Color.BLACK,Color.BLUE, Color.CYAN,Color.GREEN, Color.ORANGE,Color.PINK,Color.YELLOW,Color.WHITE}; private static final Random rand = new Random(); private static Color getC(){ return color[rand.nextInt(color.length)]; } public SleepMethodTest(){ t = new Thread(new Runnable(){ int x = 30; int y =50; @Override public void run() { // TODO 自动生成的方法存根 while(true){ try{ Thread.sleep(100); }catch(InterruptedException e){ e.printStackTrace(); } Graphics graphics = getGraphics(); graphics.setColor(getC()); graphics.drawLine(x, y, 100, y++); if (y > 80){ y = 50 ; } } } }); t.start(); } /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 init(new SleepMethodTest(),100 ,100 ); } public static void init(JFrame jframe , int width , int height){ jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jframe.setSize(width, height); jframe.setVisible(true); }}
线程的加入
线程的加入顾名思义即为将一个线程加入到当前的线程,当前线程会在加入的线程运行完后继续执行,线程的加入使用join()方法,代码实例:
/** * */package test线程;import java.awt.BorderLayout;import javax.swing.JFrame;import javax.swing.JProgressBar;/** - @author 寒 - */public class JoinTest extends JFrame { private Thread threadA; private Thread threadB; final JProgressBar progressBar = new JProgressBar(); final JProgressBar progressBar2 = new JProgressBar(); int count = 0; /** * @param args */ public static void main(String[] args) { // TODO 自动生成的方法存根 init(new JoinTest(), 300, 300); } public JoinTest() { super(); getContentPane().add(progressBar, BorderLayout.NORTH); getContentPane().add(progressBar2, BorderLayout.SOUTH); progressBar.setStringPainted(true); progressBar2.setStringPainted(true); threadA = new Thread(new Runnable() { int count = 0; @Override public void run() { // TODO 自动生成的方法存根 while (true) { progressBar.setValue(++count); try { Thread.sleep(100); threadB.join();//先执行线程B } catch (Exception e) { e.printStackTrace(); } } } }); threadA.start(); threadB = new Thread(new Runnable() { int count = 0; @Override public void run() { // TODO 自动生成的方法存根 while (true) { progressBar2.setValue(++count); try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } if (count == 100) { break; } } } }); threadB.start(); } public static void init(JFrame frame, int width, int height) { frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(width, height); frame.setVisible(true); }}
- 线程的优先级
1).与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行。
2).线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先级为5。
3).在一个线程中开启另外一个新线程,则新开线程称为该线程的子线程,子线程初始优先级与父线程相同。
4).使用setPriority(int newPriority)方法设置线程的优先级,备选的有三个定义常量Thread.MAX_PRIORITY = 10 、Thread.MIN_PRIORITY = 1、Thread.NORM_PRIORITY= 5,自定义线程优先级的时候范围为1-10的整数。
- 线程的同步
为什么会产生线程的同步的想法?
在多个进程访问公共资源的时候,将会产生bug,示例如下:
package test线程;public class ThreadSafeTest implements Runnable { int num = 10; public static void main(String[] args) { // TODO 自动生成的方法存根 ThreadSafeTest test = new ThreadSafeTest(); Thread thread_a = new Thread(test); Thread thread_b = new Thread(test); Thread thread_c = new Thread(test); Thread thread_d = new Thread(test); thread_a.start(); thread_b.start(); thread_c.start(); thread_d.start(); } @Override public void run() { // TODO 自动生成的方法存根 while (true) { if (num > 0) { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println( "tickets :" + num--); } else{ break; } } }}
运行结果:
tickets :10tickets :9tickets :8tickets :7tickets :6tickets :5tickets :5tickets :5tickets :4tickets :3tickets :2tickets :1tickets :0tickets :-1tickets :-2
在上述线程中,某一线程将票售出,第二个线程也已经完成了判断余票的工作,于是将不存在的票继续出售,产生了线程安全问题,因此继续解决多线程之间对公共资源的访问问题。
线程的同步是利用临界资源的思想来解决问题,当多个线程需要访问一些公有资源的时候,将公有资源上锁,只允许一个进程进行访问。即可解决线程安全问题。使用synchronized(Object){// 公共资源的访问},当其他线程获取到这个锁的时候,必须等待锁被释放才能够进入该区域。Object为任意对象,每个对象都存在一个标志位,并具有0、1两个值,而这个值即为同步锁,线程运行到此处,会首先检查该对象的标志位,如果为0,即表示此同步块在其他线程中运行,此时线程处于就绪状态,反之,进入运行,并修改标志位。
修改上述代码:
@Override public void run() { // TODO 自动生成的方法存根 while (true) { synchronized ("") { if (num > 0) { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println( "tickets :" + num--); } else{ break; } } } }
运行结果:
tickets :10tickets :9tickets :8tickets :7tickets :6tickets :5tickets :4tickets :3tickets :2tickets :1
- 浅谈java线程
- 浅谈Java线程安全
- 浅谈java线程安全
- JAVA--浅谈线程
- 浅谈java线程安全
- 浅谈Java线程池
- Java线程浅谈
- 浅谈--java线程池
- Java线程池浅谈
- 浅谈线程关系(Java)
- 浅谈Java线程的生命周期
- 浅谈Java线程的生命周期
- 浅谈Java线程学习(注释心得)
- 浅谈Java线程启动与Thread.join()
- 浅谈java多线程之创建线程方式
- 浅谈我对JAVA线程的了解
- 浅谈Java中对线程的理解
- 浅谈 java线程 和 linux进程
- TransR/CTransR论文剩余部分:元组分类,文本关系抽取,结论
- hdoj 5665 Lucky 【水题】
- Python Paste Deployment
- 数据结构—排序
- blog 迁移
- JAVA--浅谈线程
- Maven教程:Maven Pom.xml文件详细解释
- Android 处理窗口控件大小,形状,像素等工具
- iOS开发-- 创建podspec文件,为自己的项目添加pod支持
- hdu 1875
- C#界面设计之通用对话框的使用
- 那些年 Android Studio 遇到的坑
- Xcode 7.3及OS X 10.11官方文件下载
- nohup一些测试