java基础学习总结——线程(二)

永不放弃,一切皆有可能!!!

只为成功找方法,不为失败找借口!

java基础学习总结——线程(二)

一、线程的优先级别

  

线程优先级别的使用范例:

 1 package cn.galc.test;
 2
 3 public class TestThread6 {
 4     public static void main(String args[]) {
 5         MyThread4 t4 = new MyThread4();
 6         MyThread5 t5 = new MyThread5();
 7         Thread t1 = new Thread(t4);
 8         Thread t2 = new Thread(t5);
 9         t1.setPriority(Thread.NORM_PRIORITY + 3);// 使用setPriority()方法设置线程的优先级别,这里把t1线程的优先级别进行设置
10         /*
11          * 把线程t1的优先级(priority)在正常优先级(NORM_PRIORITY)的基础上再提高3级
12          * 这样t1的执行一次的时间就会比t2的多很多     
13          * 默认情况下NORM_PRIORITY的值为5
14          */
15         t1.start();
16         t2.start();
17         System.out.println("t1线程的优先级是:" + t1.getPriority());
18         // 使用getPriority()方法取得线程的优先级别,打印出t1的优先级别为8
19     }
20 }
21
22 class MyThread4 implements Runnable {
23     public void run() {
24         for (int i = 0; i <= 1000; i++) {
25             System.out.println("T1:" + i);
26         }
27     }
28 }
29
30 class MyThread5 implements Runnable {
31     public void run() {
32         for (int i = 0; i <= 1000; i++) {
33             System.out.println("===============T2:" + i);
34         }
35     }
36 }

  run()方法一结束,线程也就结束了。

二、线程同步

  

synchronized关键字的使用范例:

 1 package cn.galc.test;
 2
 3 public class TestSync implements Runnable {
 4     Timer timer = new Timer();
 5
 6     public static void main(String args[]) {
 7         TestSync test = new TestSync();
 8         Thread t1 = new Thread(test);
 9         Thread t2 = new Thread(test);
10         t1.setName("t1");// 设置t1线程的名字
11         t2.setName("t2");// 设置t2线程的名字
12         t1.start();
13         t2.start();
14     }
15
16     public void run() {
17         timer.add(Thread.currentThread().getName());
18     }
19 }
20
21 class Timer {
22     private static int num = 0;
23
24     public/* synchronized */void add(String name) {// 在声明方法时加入synchronized时表示在执行这个方法的过程之中当前对象被锁定
25         synchronized (this) {
26             /*
27              * 使用synchronized(this)来锁定当前对象,这样就不会再出现两个不同的线程同时访问同一个对象资源的问题了 只有当一个线程访问结束后才会轮到下一个线程来访问
28              */
29             num++;
30             try {
31                 Thread.sleep(1);
32             } catch (InterruptedException e) {
33                 e.printStackTrace();
34             }
35             System.out.println(name + ":你是第" + num + "个使用timer的线程");
36         }
37     }
38 }

线程死锁的问题:

 1 package cn.galc.test;
 2
 3 /*这个小程序模拟的是线程死锁的问题*/
 4 public class TestDeadLock implements Runnable {
 5     public int flag = 1;
 6     static Object o1 = new Object(), o2 = new Object();
 7
 8     public void run() {
 9         System.out.println(Thread.currentThread().getName() + "的flag=" + flag);
10         /*
11          * 运行程序后发现程序执行到这里打印出flag以后就再也不往下执行后面的if语句了
12          * 程序也就死在了这里,既不往下执行也不退出
13          */
14
15         /* 这是flag=1这个线程 */
16         if (flag == 1) {
17             synchronized (o1) {
18                 /* 使用synchronized关键字把对象01锁定了 */
19                 try {
20                     Thread.sleep(500);
21                 } catch (InterruptedException e) {
22                     e.printStackTrace();
23                 }
24                 synchronized (o2) {
25                     /*
26                      * 前面已经锁住了对象o1,只要再能锁住o2,那么就能执行打印出1的操作了
27                      * 可是这里无法锁定对象o2,因为在另外一个flag=0这个线程里面已经把对象o1给锁住了
28                      * 尽管锁住o2这个对象的线程会每隔500毫秒睡眠一次,可是在睡眠的时候仍然是锁住o2不放的
29                      */
30                     System.out.println("1");
31                 }
32             }
33         }
34         /*
35          * 这里的两个if语句都将无法执行,因为已经造成了线程死锁的问题
36          * flag=1这个线程在等待flag=0这个线程把对象o2的锁解开,
37          * 而flag=0这个线程也在等待flag=1这个线程把对象o1的锁解开
38          * 然而这两个线程都不愿意解开锁住的对象,所以就造成了线程死锁的问题
39          */
40
41         /* 这是flag=0这个线程 */
42         if (flag == 0) {
43             synchronized (o2) {
44                 /* 这里先使用synchronized锁住对象o2 */
45                 try {
46                     Thread.sleep(500);
47                 } catch (InterruptedException e) {
48                     e.printStackTrace();
49                 }
50                 synchronized (o1) {
51                     /*
52                      * 前面已经锁住了对象o2,只要再能锁住o1,那么就能执行打印出0的操作了 可是这里无法锁定对象o1,因为在另外一个flag=1这个线程里面已经把对象o1给锁住了 尽管锁住o1这个对象的线程会每隔500毫秒睡眠一次,可是在睡眠的时候仍然是锁住o1不放的
53                      */
54                     System.out.println("0");
55                 }
56             }
57         }
58     }
59
60     public static void main(String args[]) {
61         TestDeadLock td1 = new TestDeadLock();
62         TestDeadLock td2 = new TestDeadLock();
63         td1.flag = 1;
64         td2.flag = 0;
65         Thread t1 = new Thread(td1);
66         Thread t2 = new Thread(td2);
67         t1.setName("线程td1");
68         t2.setName("线程td2");
69         t1.start();
70         t2.start();
71     }
72 }

  解决线程死锁的问题最好只锁定一个对象,不要同时锁定两个对象

生产者消费者问题:

 1 package cn.galc.test;
 2
 3 /*    范例名称:生产者--消费者问题
 4  *     源文件名称:ProducerConsumer.java
 5  *    要  点:
 6  *        1. 共享数据的不一致性/临界资源的保护
 7  *        2. Java对象锁的概念
 8  *        3. synchronized关键字/wait()及notify()方法
 9  */
10
11 public class ProducerConsumer {
12     public static void main(String args[]){
13             SyncStack stack = new SyncStack();
14             Runnable p=new Producer(stack);
15             Runnable c = new Consumer(stack);
16             Thread p1 = new Thread(p);
17             Thread c1 = new Thread(c);
18
19             p1.start();
20             c1.start();
21     }
22 }
23
24
25 class SyncStack{  //支持多线程同步操作的堆栈的实现
26     private int index = 0;
27     private char []data = new char[6];
28     public synchronized void push(char c){
29         if(index == data.length){
30         try{
31                 this.wait();
32         }catch(InterruptedException e){}
33         }
34         this.notify();
35         data[index] = c;
36         index++;
37     }
38     public synchronized char pop(){
39         if(index ==0){
40             try{
41                 this.wait();
42             }catch(InterruptedException e){}
43         }
44         this.notify();
45         index--;
46         return data[index];
47     }
48 }
49
50
51 class  Producer implements Runnable{
52     SyncStack stack;
53     public Producer(SyncStack s){
54         stack = s;
55     }
56     public void run(){
57         for(int i=0; i<20; i++){
58             char c =(char)(Math.random()*26+‘A‘);
59             stack.push(c);
60             System.out.println("produced:"+c);
61             try{
62                 Thread.sleep((int)(Math.random()*1000));
63             }catch(InterruptedException e){
64             }
65         }
66     }
67 }
68
69
70 class Consumer implements Runnable{
71     SyncStack stack;
72     public Consumer(SyncStack s){
73         stack = s;
74     }
75     public void run(){
76         for(int i=0;i<20;i++){
77             char c = stack.pop();
78             System.out.println("消费:"+c);
79             try{
80                 Thread.sleep((int)(Math.random()*1000));
81             }catch(InterruptedException e){
82             }
83         }
84     }
85 }

时间: 2024-10-11 03:35:45

java基础学习总结——线程(二)的相关文章

java基础学习总结——线程(一)

永不放弃,一切皆有可能!!! 只为成功找方法,不为失败找借口! java基础学习总结——线程(一) 一.线程的基本概念 线程理解:线程是一个程序里面不同的执行路径 每一个分支都叫做一个线程,main()叫做主分支,也叫主线程. 程只是一个静态的概念,机器上的一个.class文件,机器上的一个.exe文件,这个叫做一个 进程.程序的执行过程都是这样的:首先把程序的代码放到内存的代码区里面,代码放到代码区后并没有马上开始执行,但这时候说明了一个进程准备开始,进程已 经产生了,但还没有开始执行,这就是

java基础学习总结-----线程(一)

转:基础学习总结----线程(一)http://www.cnblogs.com/xdp-gacl/p/3633936.htmljava 一.线程的概念 线程:线程是一个程序里面不同的执行路径 进程:一个静态的概念,机器上的一个.class文件,机器上的一个.exe文件,这个叫做一个进程. 程序的执行过程: 1.首先把程序的代码放到内存的代码区里面,代码放到代码区后并没有马上开始执行,但这时候说明了一个进程准备开始,进程已经产生,但还没有开始执行,这就是进程.其实是2.一进程的执行指的是进程里面主

Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API

不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权限修饰符,默认访问, 类,方法,成员变量 private 权限修饰符,私有访问, 方法,成员变量 static 静态修饰符 方法,成员变量 final 最终修饰符 类,方法,成员变量,局部变量 abstract 抽象修饰符 类 ,方法 我们编写程序时,权限修饰符一般放于所有修饰符之前,不同的权限修饰

Java基础-学习笔记(二)

1.java的普通数据类型 数据类型 关键字 占用字节数 布尔型 boolean 1 字节型 byte 1 字符型 char 1 短整型 short 2 整型 int 4 长整型 long 8 浮点型 float 4 双精度型 double 8 2.普通数据类型之间的转换,一个例子说明情况 1 public static void main(String args[]) 2 { 3 int x=1; 4 float f=2.0f;//如果不加f,则默认为double类型 5 double e=f

[ 转载 ] Java基础学习总结——线程(一)

http://www.cnblogs.com/xdp-gacl/p/3633936.html 原文地址:https://www.cnblogs.com/ILoke-Yang/p/8137415.html

JAVA基础再回首(二十五)——Lock锁的使用、死锁问题、多线程生产者和消费者、线程池、匿名内部类使用多线程、定时器、面试题

JAVA基础再回首(二十五)--Lock锁的使用.死锁问题.多线程生产者和消费者.线程池.匿名内部类使用多线程.定时器.面试题 版权声明:转载必须注明本文转自程序员杜鹏程的博客:http://blog.csdn.net/m366917 我们来继续学习多线程 Lock锁的使用 虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,为了更清晰的表达如何加锁和释放锁,JDK5以后提供了一个新的锁对象Lock Lock void lock():获取锁 v

java基础学习总结——GUI编程(二)

永不放弃,一切皆有可能!!! 只为成功找方法,不为失败找借口! java基础学习总结——GUI编程(二) 一.事件监听 测试代码一: 1 package cn.javastudy.summary; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 6 public class TestActionEvent { 7 public static void main(String args[]) { 8 Frame f = new Frame("

Java基础学习——数组初识(1)

Java基础学习--数组初识(1) 1什么是数组 Java中常见的一种数据结构就是数组,数组可以分为一维数组.二维数组和多维数组. 数组是由一组相同的变量组成的数据类型,数组中每个元素具有相同的数据类型,数组中的每个元素都可以用一个统一的数组名和下标来确定. 2 数组的使用 数组的一般使用步骤: 声明数组 分配内存给该数组 下面是一维数组为例: 数据类型  数组名 []: 数组名 = new 数据类型 [数据个数]: 2.1一维数组的声明与赋值 1.数组的声明 int  num [];    

Java基础学习总结——Java对象的序列化和反序列化

一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些s