在java中有两种方式产生一个thread。 java.lang.Thread java.lang.Runnable
1 某一个类实现Runnable接口,重点是重载run()方法;
2 某一类继承Thread类,并重载run()方法。
当某一个类是以上两种方法之一,当为该类new一个对象时,该对象并没有直接进入thread,直到执行 object.start()时,该对象才变成一个thread。并开始执行run()方法中的语句。
在多线程中,每个线程都有自己的数据空间,同时他们还可以访问进程的数据空间。多线程访问进程的数据空间的时候,需要考虑同步。
thread中常用的方法:
1 java.lang.Object.wait() 释放锁,(并且进入线程不可调度)并且直到有notify()或notifityAll()是才会继续往下执 行。(进入线程可调度)
2 java.lang.Object.notify() 释放锁,并且唤醒wait()的线程。
3 java.lang.Thread.sleep() 不释放锁,线程睡眠一段时间之后,继续执行。
4
java为每个对象分配一根锁。同时为类分配一个锁。当我们对类中的方法fun1使用synchronize,另一个方法fun2也是用synchronize,(假设线程1,2中执行的fun1,fun2属于同一个对象,(这样保证fun1,fun2使用的是同一个锁))当线程1执行fun1时,被线程2被调度,并且线程2执行fun2,那么此时线程2无法执行fun2,因为执行锁被fun1占用。
thread要考虑线程同步的问题,最典型的是生产与消费问题。有一个仓库,生产者生产的产品放入该仓库,消费者从该仓库中取出产品。仓库满之后,不允许在向其中放入,而仓库空时不允许从其中取出。 在这里。仓库是生产线程和消费线程的共享资源,这个共享资源被这2个线程改变。
public class App {
private Test test = new Test();
class Add extends Thread {
public void run(){
while(true) {
try {
test.product();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
class Sub extends Thread {
public void run(){
while(true){
try {
test.consume();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
public Add getAdd(){
return new Add();
}
public Sub getSub(){
return new Sub();
}
public static void main (String [] args){
App app = new App();
App.Add addThread = app.getAdd();
Sub subThread = app.getSub();
subThread.start();
addThread.start();
}
}
当线程之间不采用同步时:test的类如下:
public class Test {
private static int containerMemory = 4;
private int container ;
public void product()throws Exception{
System.out.println(Thread.currentThread().getName()+ " Product begin "+containerMemory);
if (containerMemory >= 10){
System.out.println("product wait");
//this.wait();
}else {
container = containerMemory ;
Thread.sleep(1000);
container ++ ;
containerMemory = container;
System.out.println(Thread.currentThread().getName()+ " Product end "+containerMemory);
//this.notifyAll();
}
}
public void consume() throws Exception {
System.out.println(Thread.currentThread().getName()+" consume begin "+containerMemory);
if (containerMemory <= 0){
System.out.println("consume wait");
//this.wait();
}else {
container = containerMemory ;
container -- ;
containerMemory = container;
System.out.println(Thread.currentThread().getName()+" consume end "+containerMemory);
//this.notifyAll();
}
}
}
对应的打印为:
Thread-1 consume begin 4
Thread-1 consume end 3
Thread-0 Product begin 4
Thread-1 consume begin 3
Thread-1 consume end 2
Thread-1 consume begin 2
Thread-1 consume end 1
Thread-1 consume begin 1
Thread-1 consume end 0
Thread-1 consume begin 0
consume wait
Thread-0 Product end 4
Thread-0 Product begin 4
Thread-0 Product end 5
Thread-0 Product begin 5
Thread-0 Product end 6
Thread-0 Product begin 6
Thread-0 Product end 7
Thread-0 Product begin 7
Thread-0 Product end 8
Thread-0 Product begin 8
Thread-0 Product end 9
Thread-0 Product begin 9
Thread-0 Product end 10
Thread-0 Product begin 10
product wait
可以看到上面打印的蓝色部分出现了错误。product的过程被consume打断。product读取containerMemory之后,修改containerMemory,然后再把修改之写入containerMemory,但是在读containerMemory之后,写containerMemory之前被consume打断,而consume打断之后又修改了containerMemory的值。导致produce的containerMemory值过期。
现在给test加上同步:
public class Test {
private static int containerMemory = 4;
private int container ;
public synchronized void product()throws Exception{
System.out.println(Thread.currentThread().getName()+ " Product begin "+containerMemory);
if (containerMemory >= 10){
System.out.println("product wait");
this.wait();
}else {
container = containerMemory ;
Thread.sleep(1000);
container ++ ;
containerMemory = container;
System.out.println(Thread.currentThread().getName()+ " Product end "+containerMemory);
this.notifyAll();
}
}
public synchronized void consume() throws Exception {
System.out.println(Thread.currentThread().getName()+" consume begin "+containerMemory);
if (containerMemory <= 0){
System.out.println("consume wait");
this.wait();
}else {
container = containerMemory ;
container -- ;
Thread.sleep(1000);
containerMemory = container;
System.out.println(Thread.currentThread().getName()+" consume end "+containerMemory);
this.notifyAll();
}
}
}
打印为:
Thread-1 consume begin 4
Thread-1 consume end 3
Thread-1 consume begin 3
Thread-1 consume end 2
Thread-1 consume begin 2
Thread-1 consume end 1
Thread-1 consume begin 1
Thread-1 consume end 0
Thread-1 consume begin 0
consume wait
Thread-0 Product begin 0
Thread-0 Product end 1
Thread-0 Product begin 1
Thread-0 Product end 2
Thread-0 Product begin 2
Thread-0 Product end 3
Thread-1 consume begin 3
Thread-1 consume end 2
Thread-1 consume begin 2
Thread-1 consume end 1
Thread-1 consume begin 1
Thread-1 consume end 0
Thread-1 consume begin 0
consume wait
Thread-0 Product begin 0
Thread-0 Product end 1
Thread-0 Product begin 1
Thread-0 Product end 2
Thread-0 Product begin 2
Thread-0 Product end 3
Thread-0 Product begin 3
Thread-0 Product end 4
Thread-0 Product begin 4
Thread-0 Product end 5
Thread-0 Product begin 5
Thread-0 Product end 6
Thread-0 Product begin 6
Thread-0 Product end 7
Thread-0 Product begin 7
Thread-0 Product end 8
Thread-1 consume begin 8
Thread-1 consume end 7
Thread-1 consume begin 7
Thread-1 consume end 6
Thread-1 consume begin 6
Thread-1 consume end 5
Thread-1 consume begin 5
Thread-1 consume end 4
Thread-1 consume begin 4
Thread-1 consume end 3
Thread-1 consume begin 3
Thread-1 consume end 2
Thread-1 consume begin 2
Thread-1 consume end 1
Thread-1 consume begin 1
Thread-1 consume end 0
Thread-1 consume begin 0
consume wait
Thread-0 Product begin 0
Thread-0 Product end 1
Thread-0 Product begin 1
Thread-0 Product end 2
Thread-0 Product begin 2
Thread-0 Product end 3
Thread-0 Product begin 3
Thread-0 Product end 4
Thread-1 consume begin 4
Thread-1 consume end 3
Thread-1 consume begin 3
Thread-1 consume end 2
Thread-1 consume begin 2
Thread-1 consume end 1
Thread-1 consume begin 1
Thread-1 consume end 0
Thread-1 consume begin 0
consume wait
Thread-0 Product begin 0
可以看出cosume的过程不会被product打断,同样product也不会被consume打断。
分享到:
相关推荐
浅谈JAVA中多线程的实现
详细介绍了java中多线程的应用!对于初学java的同学们 很有帮助!
用java平台利用java的多线程特点,编写进度条的现实以及当前时间的实时更新。
JAVA中多线程技术的实现.pdf
java多线程实现大批量数据切分成指定份数的数据,然后多线程处理入库或者导出,线程的个数和每份数据的数量都可以控制
浅谈JAVA中多线程的实现.pdf
Java中多线程机制模拟《泰坦尼克号》精彩片段
java多线程进度条
Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口 9.4 线程的常用方法 9.5 GUI线程 9.6 线程同步 9.7 在同步方法中使用wait()、notify 和notifyAll()方法 9.8 挂起、恢复和终止线程 ...
Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式上传文件Java多线程设计模式...
Java多线程读大文件 java多线程写文件:多线程往队列中写入数据
多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字和示例来介绍与java线程相关的设计模式理念
Java 高并发多线程编程系列案例代码 & 教程 & 面试题集锦! !! 包括但不限于线程安全性, atomic包下相关类、CAS原理、Unsafe类、synchronized关键字等的使用及注意事项,
java多线程PPT 多线程基本概念 创建线程的方式 线程的挂起与唤醒 多线程问题
多线程启动.java多线程启动.java多线程启动.java多线程启动.java
论文参考,JAVAJAVA多线程教学演示系统论文
Java中多线程的学习的自我小结,有多线程的意思,多线程常见的控制方法等内容
教程,讲的很详细!!!!1
java多线程的使用方法如何使用,怎么使用,使用过程中有什么要注意的
一个java 多线程操作数据库应用程序!!!