首页 技术 正文
技术 2022年11月18日
0 收藏 789 点赞 4,941 浏览 10972 个字

《Java多线程编程核心技术》读后感(一)

1、继承Thread

package First;public class MyThread extends Thread {
public void run() {
super.run();
System.out.println("mythread");
}
}
package First;public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("main");
}
}

《Java多线程编程核心技术》读后感(一)

在使用多线程技术时,代码的运行结果与代码执行顺序或调用顺序是无关的。

package First;public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
myThread.start();
System.out.println("main");
}
}

《Java多线程编程核心技术》读后感(一)

多次执行start(),会出现java.lang.IllegalThreadStateException异常

package First;public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.run();
System.out.println("main");
}
}

start()通知“”线程规划器“”此线程已经准备就绪,等待调用线程对象的run(),具有异步效果。如果直接调用run(),则是同步,从上到下顺序依次执行

《Java多线程编程核心技术》读后感(一)

执行start()顺序不代表线程启动的顺序。

2、实现runnable接口

package First;public class MyRunnable implements Runnable {    @Override
public void run() {
System.out.println("运行中");
}}
package First;public class Run {
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
Thread thread = new Thread(runnable);
thread.start();
System.out.println("运行结束");
}
}

《Java多线程编程核心技术》读后感(一)

Thread构造函数:

《Java多线程编程核心技术》读后感(一)

构造函数Thread(Runnable target)意味着不光可以传入runnable接口的对象,还可以传入Thread类的对象,这样做完全可以将一个Thread对象的run()方法交给其他线程进行调用

实例变量与线程安全

(1)不共享数据

package First;public class MyThread extends Thread {
private int count = 5;
public MyThread(String name) {
super();
//设置线程名称
this.setName(name);
}
public void run() {
super.run();
while(count>0) {
count--;
System.out.println("由"+this.currentThread().getName()+"计算,count="+count);
}
}
}
package First;public class Test {
public static void main(String[] args) {
MyThread a = new MyThread("A");
MyThread b = new MyThread("B");
MyThread c = new MyThread("C");
a.start();
b.start();
c.start();
System.out.println("main");
}
}

《Java多线程编程核心技术》读后感(一)

(2)共享数据

package First;public class MyThread extends Thread {
private int count = 5;
public void run() {
super.run();
  //此实例不要用for语句,因为使用同步后其他线程就得不到运行的机会了
count--;
System.out.println("由"+this.currentThread().getName()+"计算,count="+count); }
}
package First;public class Test {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread a = new Thread(myThread,"A");
Thread b = new Thread(myThread,"B");
Thread c = new Thread(myThread,"C");
Thread d = new Thread(myThread,"D");
Thread e = new Thread(myThread,"E");
a.start();
b.start();
c.start();
d.start();
e.start();
System.out.println("main");
}
}

非线程安全问题(随机):主要是指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流程

《Java多线程编程核心技术》读后感(一)

某些JVM中,i–的操作分成三步:

1)取得原有的i值

2)计算i-1

3)对i进行赋值

在这三个步骤中,如果有多个线程同时访问,那么一定会出现非线程安全问题

package First;public class MyThread extends Thread {
private int count = 5;
synchronized public void run() {
super.run(); count--;
System.out.println("由"+this.currentThread().getName()+"计算,count="+count); }
}

程序改成上述,就不会出现问题了

《Java多线程编程核心技术》读后感(一)

一个非线程安全的例子:

package First;public class LoginServlet {
private static String usernameRef;
private static String passwordRef; public static void doPost(String username,String password) {
try {
usernameRef = username;
if(username.equals("a")) {
Thread.sleep(5000);
}
passwordRef = password;
System.out.println("username="+usernameRef+" password="+password);
} catch (Exception e) {
// TODO: handle exception
}
}
}
package First;public class ALogin extends Thread{
public void run() {
LoginServlet.doPost("a", "aa");
}
}
package First;public class BLogin extends Thread{
public void run() {
LoginServlet.doPost("b", "bb");
}
}
package First;public class Run {
public static void main(String[] args) {
ALogin a = new ALogin();
a.start();
BLogin b = new BLogin();
b.start(); }
}

《Java多线程编程核心技术》读后感(一)

解决非线程安全问题使用synchronized

package First;public class LoginServlet {
private static String usernameRef;
private static String passwordRef; synchronized public static void doPost(String username,String password) {
try {
usernameRef = username;
if(username.equals("a")) {
Thread.sleep(5000);
}
passwordRef = password;
System.out.println("username="+usernameRef+" password="+password);
} catch (Exception e) {
// TODO: handle exception
}
}
}

《Java多线程编程核心技术》读后感(一)

留意i–与System.out.println()

println()与i++联合使用时有可能出现另外一种异常情况

package First;public class MyThread extends Thread {
private int i = 5;
public void run() {
//代码i--由前面项目中单独一行运行改成在当前项目中在println()方法中直接进行打印
System.out.println("i="+(i--)+" threadName="+Thread.currentThread().getName());
}
}
package First;public class Run {
public static void main(String[] args) {
MyThread run = new MyThread();
Thread t1 = new Thread(run);
Thread t2 = new Thread(run);
Thread t3 = new Thread(run);
Thread t4 = new Thread(run);
Thread t5 = new Thread(run);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}

《Java多线程编程核心技术》读后感(一)

《Java多线程编程核心技术》读后感(一)

虽然println()内部是同步的,但i–的操作却是在进入println()之前发生的。所以为了防止非线程安全问题,还是应该继续使用同步方法

currentTread()方法

package First;public class MyThread extends Thread {
public MyThread() {
System.out.println("构造方法的打印: "+Thread.currentThread().getName());
}
public void run() {
System.out.println("run方法打印:"+Thread.currentThread().getName());
}
}
package First;public class Run {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
}
}

《Java多线程编程核心技术》读后感(一)

package First;public class Run {
public static void main(String[] args) {
MyThread myThread = new MyThread();
//myThread.start();
myThread.run();
}
}

《Java多线程编程核心技术》读后感(一)

由第一个实验可以看出:Mythread的构造函数是被main函数调用的,而run()方法是被名称为Thread-0调用的

由第二个实验可以看出:直接调用run()的话,则调用者名称为main

package First;public class CountOperate extends Thread {
public CountOperate() {
System.out.println("CountOperation---begin");
System.out.println("Thread.currentThread().getName()="+Thread.currentThread().getName());
System.out.println("this.getName()"+this.getName());
System.out.println("CountOperation---end");
}
public void run() {
System.out.println("CountOperation---begin");
System.out.println("Thread.currentThread().getName()="+Thread.currentThread().getName());
System.out.println("this.getName()"+this.getName());
System.out.println("CountOperation---end");
}
}
package First;public class Run {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName());
CountOperate countOperate = new CountOperate();
Thread thread = new Thread(countOperate);
thread.setName("A");
thread.start(); }
}

《Java多线程编程核心技术》读后感(一)

isLive()

判断当前线程是否处于活跃状态

package First;public class MyThread extends Thread {    public void run() {
System.out.println("run="+this.isAlive());
}
}
package First;public class Run {
public static void main(String[] args) {
MyThread myThread = new MyThread();
System.out.println("begin="+myThread.isAlive());
myThread.start();
System.out.println("end="+myThread.isAlive()); }
}

《Java多线程编程核心技术》读后感(一)

注意最后一个println()的值是不确定的

package First;public class CountOperate extends Thread {
public CountOperate() {
System.out.println("CountOperation---begin");
System.out.println("Thread.currentThread().getName()="+Thread.currentThread().getName());
System.out.println("Thread.currentThread().isAlive()="+Thread.currentThread().isAlive());
System.out.println("this.getName()"+this.getName());
System.out.println("this.isAlive()"+this.isAlive());
System.out.println("CountOperation---end");
}
public void run() {
System.out.println("run---begin");
System.out.println("Thread.currentThread().getName()="+Thread.currentThread().getName());
System.out.println("Thread.currentThread().isAlive()="+Thread.currentThread().isAlive());
System.out.println("this.getName()"+this.getName());
System.out.println("this.isAlive()"+this.isAlive());
System.out.println("run---end");
}
}
package First;
public class Run {
public static void main(String[] args) {
CountOperate countOperate = new CountOperate();
Thread thread = new Thread(countOperate);
System.out.println("main begin t1 isAlive="+thread.isAlive());
thread.setName("A");
thread.start();
System.out.println("main end t1 isAlive="+thread.isAlive()); }
}

《Java多线程编程核心技术》读后感(一)

如果将线程对象以构造参数的方式传递给Thread对象进行start()启动时,运行的结果和前面实例的结果有些差异。造成这样的差异的原因还是来自于Thread.currentThread()和this之间的差异(具体解释参考:http://blog.csdn.net/yezis/article/details/57513130

sleep()方法

是在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)这个“正在执行的线程”是指this.currentThread()返回的线程

package First;public class MyThread extends Thread {    public void run() {
try {
System.out.println("run threadName="+this.currentThread().getName()+" begin");
Thread.sleep(2000);
System.out.println("run threadName="+this.currentThread().getName()+" end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
package First;
public class Run {
public static void main(String[] args) {
MyThread myThread = new MyThread();
System.out.println("begin = " +System.currentTimeMillis());
myThread.run();
//myThread.start();
System.out.println("end = " +System.currentTimeMillis()); }
}

《Java多线程编程核心技术》读后感(一)

package First;
public class Run {
public static void main(String[] args) {
MyThread myThread = new MyThread();
System.out.println("begin = " +System.currentTimeMillis());
//myThread.run();
myThread.start();
System.out.println("end = " +System.currentTimeMillis()); }
}

《Java多线程编程核心技术》读后感(一)

getId()方法

作用是获取线程的唯一标识

package First;
public class Run {
public static void main(String[] args) {
Thread runThrad = Thread.currentThread();
System.out.println(runThrad.getId()); }
}

《Java多线程编程核心技术》读后感(一)

停止线程

Thread.stop()是不安全的,已经被弃用

大多数使用Thread.interrupt(),但这个方法不会终止一个正在运行的线程,还需要加入一个判断才可以完成线程的停止

《Java多线程编程核心技术》读后感(一)

停不了的线程

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

package First;public class MyThread extends Thread {    public void run() {
super.run();
for(int i = 0;i <50000;i++) {
System.out.println("i"+(i+1));
}
}}
package First;public class Run {
public static void main(String[] args) {
try {
Thread myThread= new MyThread();
myThread.start();
Thread.sleep(2000);
Thread.interrupted();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
} }
}

《Java多线程编程核心技术》读后感(一)

说明调用interrupt并没有停止线程

判断线程是否是停止状态

this.interrupted();是static方法,测试当前线程是否已经中断,当前线程是指运行this.interrupted()方法的线程

package First;public class Run {
public static void main(String[] args) {
try {
Thread myThread= new MyThread();
myThread.start();
Thread.sleep(2000);
Thread.interrupted();
System.out.println("是否停止1? = "+Thread.interrupted());
System.out.println("是否停止1? = "+Thread.interrupted());
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
} System.out.println("end");
}
}

《Java多线程编程核心技术》读后感(一)

线程并未停止,这也说明了interrupted()方法的解释:测试当前线程是否已经中断。这个“当前线程”是main,它从未中断过,所以打印的是两false

package First;public class Run {
public static void main(String[] args) { Thread.currentThread().interrupt();
System.out.println("是否停止1? = " + Thread.interrupted());
System.out.println("是否停止1? = " + Thread.interrupted()); System.out.println("end");
}
}

《Java多线程编程核心技术》读后感(一)

为什么第2个布尔值是false呢?:

《Java多线程编程核心技术》读后感(一)

this.isInterrupted():方法不是static的

package First;public class Run {
public static void main(String[] args) {
try {
Thread myThread= new MyThread();
myThread.start();
Thread.sleep(1000);
Thread.interrupted();
System.out.println("是否停止1? = "+myThread.isInterrupted());
System.out.println("是否停止1? = "+myThread.isInterrupted());
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
} System.out.println("end");
}
}

两者之间的区别:

《Java多线程编程核心技术》读后感(一)

能停止的线程-异常法(这两个实验我都没成功)

package First;public class MyThread extends Thread {    public void run() {
super.run();
for(int i = 0;i <50000;i++) {
if(Thread.interrupted()) {
System.out.println("已经是停止的状态,退出");
break;
}
System.out.println("i"+(i+1));
}
}}
package First;public class Run {
public static void main(String[] args) {
try {
Thread myThread= new MyThread();
myThread.start();
Thread.sleep(2000);
Thread.interrupted();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
} System.out.println("end");
}
}

《Java多线程编程核心技术》读后感(一)

虽然停止了线程,但如果for语句下面还有语句,还是会继续执行的

package First;public class MyThread extends Thread {    public void run() {
super.run();
try {
for(int i = 0;i <50000;i++) {
if(Thread.interrupted()) {
System.out.println("已经是停止的状态,退出");
break;
}
System.out.println("i"+(i+1));
}
System.out.println("我在for下面");
} catch (Exception e) {
System.out.println("进入MyThread.java类run方法中的catch");
} }}
package First;public class Run {
public static void main(String[] args) {
try {
Thread myThread= new MyThread();
myThread.start();
Thread.sleep(2000);
Thread.interrupted();
} catch (InterruptedException e) {
System.out.println("main catch");
e.printStackTrace();
} System.out.println("end");
}
}

《Java多线程编程核心技术》读后感(一)

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,020
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,513
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,359
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,142
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,772
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,850