並行和併發:
進程和線程:
多線程的優勢:
JAVA中創建進程的方式:
package com.anonymous.javase.day06;
import java.io.IOException;
import java.util.List;
/*java操作進程:
在java代碼中如何運行一個進程().
方式1:Runtime類中的exec方法;
方式2:ProcessBuilder類中的start方法:
*/
public class Demo1 {
public static void main(String[] args) throws IOException {
//方式1:啓動Runtime的exec方法
Runtime runtime = Runtime.getRuntime();
runtime.exec("notepad");
runtime.exec("calc");
//方式2:ProcessBuilder的start
ProcessBuilder builder = new ProcessBuilder("notepad");
builder.start();
}
}
java中創建線程的方式:
創建和啓動線程,傳統有兩種方式: 方式1:繼承Tread類; 方式2:實現Runnable接口; 線程類(java.lang.Tread):Tread類和Tread的子類才能稱之爲線程類, 主線程(main方法是主線程);
Thread繼承方式:
package com.anonymous.javase.day06;
//繼承和實現兩種方式啓動線程
//使用Thread方式
public class Demo2 extends Thread {
/**
* 創建和啓動線程,傳統有兩種方式: 方式1:繼承Tread類; 方式2:實現Runnable接口;
* 線程類(java.lang.Tread):Tread類和Tread的子類才能稱之爲線程類, 主線程(main方法是主線程);
*/
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println("打遊戲!" + i);
}
}
public static void main(String[] args) {
for (int i = 1; i <= 50; i++) {
System.out.println("敲代碼!" + i);
if (i == 10) {
Demo2 demo2 = new Demo2();
demo2.start();
}
/**
* 敲代碼!1 敲代碼!2 敲代碼!3 敲代碼!4 敲代碼!5 敲代碼!6 敲代碼!7 敲代碼!8 敲代碼!9 敲代碼!10
* 敲代碼!11 敲代碼!12 敲代碼!13 敲代碼!14 敲代碼!15 敲代碼!16 敲代碼!17 敲代碼!18 敲代碼!19
* 敲代碼!20 (<這裏纔開始讓線程><>)打遊戲!1 敲代碼!21 打遊戲!2 敲代碼!22 打遊戲!3 敲代碼!23 打遊戲!4 打遊戲!5 敲代碼!24
* 打遊戲!6 打遊戲!7 敲代碼!25 打遊戲!8 打遊戲!9 敲代碼!26 打遊戲!10 敲代碼!27 打遊戲!11 敲代碼!28
* 敲代碼!29 打遊戲!12 敲代碼!30 打遊戲!13 敲代碼!31 打遊戲!14 敲代碼!32 打遊戲!15 敲代碼!33
* 打遊戲!16 敲代碼!34 打遊戲!17 敲代碼!35 敲代碼!36 打遊戲!18 敲代碼!37 敲代碼!38 打遊戲!19
* 敲代碼!39 打遊戲!20 敲代碼!40 打遊戲!21 敲代碼!41 打遊戲!22 打遊戲!23 打遊戲!24 打遊戲!25
* 打遊戲!26 打遊戲!27 打遊戲!28 敲代碼!42 打遊戲!29 敲代碼!43 打遊戲!30 敲代碼!44 打遊戲!31
* 敲代碼!45 打遊戲!32 敲代碼!46 打遊戲!33 敲代碼!47 打遊戲!34 敲代碼!48 打遊戲!35 敲代碼!49
* 打遊戲!36 敲代碼!50 打遊戲!37 打遊戲!38 打遊戲!39 打遊戲!40 打遊戲!41 打遊戲!42 打遊戲!43
* 打遊戲!44 打遊戲!45 打遊戲!46 打遊戲!47 打遊戲!48 打遊戲!49 打遊戲!50
*/
}
}
}
Runnable實現方式:
package com.anonymous.javase.day06;
//使用Runnable
class Demo3 implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println("運行中..." + i);
}
}
public static void main(String[] args) {
for (int i = 1; i <= 50; i++) {
System.out.println("運行的方式..." + i);
if (i == 20) {
Runnable demo3 = new Demo3();
Thread thread = new Thread(demo3);
thread.start();
}
/**
* 運行的方式...1 運行的方式...2 運行的方式...3 運行的方式...4 運行的方式...5 運行的方式...6
* 運行的方式...7 運行的方式...8 運行的方式...9 運行的方式...10 運行的方式...11 運行的方式...12
* 運行的方式...13 運行的方式...14 運行的方式...15 運行的方式...16 運行的方式...17 運行的方式...18
* 運行的方式...19 運行的方式...20 運行的方式...21 運行的方式...22 運行的方式...23 運行的方式...24
* 運行的方式...25 <到25的時候才讓出線程><>運行中...1 運行的方式...26 運行中...2 運行的方式...27 運行中...3
* 運行的方式...28 運行中...4 運行的方式...29 運行中...5 運行的方式...30 運行中...6
* 運行的方式...31 運行中...7 運行的方式...32 運行中...8 運行的方式...33 運行中...9
* 運行的方式...34 運行中...10 運行的方式...35 運行中...11 運行的方式...36 運行中...12
* 運行的方式...37 運行中...13 運行的方式...38 運行中...14 運行的方式...39 運行中...15
* 運行的方式...40 運行中...16 運行的方式...41 運行中...17 運行的方式...42 運行中...18
* 運行的方式...43 運行中...19 運行的方式...44 運行中...20 運行的方式...45 運行中...21
* 運行的方式...46 運行中...22 運行的方式...47 運行中...23 運行的方式...48 運行中...24
* 運行的方式...49 運行中...25 運行的方式...50 運行中...26 運行中...27 運行中...28
* 運行中...29 運行中...30 運行中...31 運行中...32 運行中...33 運行中...34 運行中...35
* 運行中...36 運行中...37 運行中...38 運行中...39 運行中...40 運行中...41 運行中...42
* 運行中...43 運行中...44 運行中...45 運行中...46 運行中...47 運行中...48 運行中...49
* 運行中...50
*/
}
}
}
吃蘋果案列:
package com.anonymous.javase.day06;
public class Demo5 implements Runnable {
private int apple = 50;
public static void main(String[] args) {
Demo5 demo5 = new Demo5();
new Thread(demo5, "小明").start();
new Thread(demo5, "名").start();
new Thread(demo5, "紅").start();
}
@Override
public void run() {
for (int j = 50; j >= 0; j--) {
if (apple > 0) {
System.out.println(Thread.currentThread().getName() + "吃了"
+ apple + "蘋果");
apple--;
}
/**
* 名吃了50蘋果 紅吃了50蘋果 小明吃了50蘋果 紅吃了48蘋果 名吃了49蘋果 紅吃了46蘋果 紅吃了44蘋果 紅吃了43蘋果
* 小明吃了47蘋果 小明吃了41蘋果 小明吃了40蘋果 小明吃了39蘋果 小明吃了38蘋果 小明吃了37蘋果 小明吃了36蘋果
* 小明吃了35蘋果 小明吃了34蘋果 小明吃了33蘋果 小明吃了32蘋果 小明吃了31蘋果 小明吃了30蘋果 小明吃了29蘋果
* 小明吃了28蘋果 紅吃了42蘋果 紅吃了26蘋果 名吃了45蘋果 紅吃了25蘋果 小明吃了27蘋果 紅吃了23蘋果 名吃了24蘋果
* 紅吃了21蘋果 小明吃了22蘋果 紅吃了19蘋果 名吃了20蘋果 紅吃了17蘋果 小明吃了18蘋果 紅吃了15蘋果 名吃了16蘋果
* 紅吃了13蘋果 小明吃了14蘋果 紅吃了11蘋果 名吃了12蘋果 紅吃了9蘋果 小明吃了10蘋果 小明吃了6蘋果 小明吃了5蘋果
* 小明吃了4蘋果 小明吃了3蘋果 紅吃了7蘋果 紅吃了1蘋果 名吃了8蘋果 小明吃了2蘋果
*/
}
}
}
使用Thread.sleep(10).模擬網絡延遲
package com.anonymous.javase.day06;
public class Demo5 implements Runnable {
private int apple = 50;
public static void main(String[] args) {
Demo5 demo5 = new Demo5();
new Thread(demo5,"小明").start();
new Thread(demo5,"名").start();
new Thread(demo5,"紅").start();
}
@Override
public void run() {
for (int j = 50; j >=0; j--) {
if (apple>0) {
try{
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"吃了"+apple+"蘋果");
apple--;
}
}
}
}
出現了負數
解決方案:有三種方式:
package com.anonymous.javase.day06;
public class Demo5 implements Runnable {
private int apple = 50;
public static void main(String[] args) {
Demo5 demo5 = new Demo5();
new Thread(demo5,"小明").start();
new Thread(demo5,"名").start();
new Thread(demo5,"紅").start();
}
@Override
public void run() {
for (int j = 50; j >=0; j--) {
synchronized (this) {//加上synchronized代碼塊
if (apple>0) {
try{
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"吃了"+apple+"蘋果");
apple--;
}
}
}
}
}
使用synchronized同步方法
package com.anonymous.javase.day06;
public class Demo5 implements Runnable {
private int apple = 50;
public static void main(String[] args) {
Demo5 demo5 = new Demo5();
new Thread(demo5,"小明").start();
new Thread(demo5,"名").start();
new Thread(demo5,"紅").start();
}
@Override
public void run() {
for (int j = 50; j >=0; j--) {
eat();
}
}
//使用synchronized同步方法
synchronized private void eat(){
if (apple>0) {
try{
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"吃了"+apple+"蘋果");
apple--;}}}
//Thread.currentThread().getName();獲取當前線程的名稱
使用同步鎖機制:
package com.anonymous.javase.day06;
import java.util.concurrent.locks.ReentrantLock;
public class Demo5 implements Runnable {
private final ReentrantLock lock = new ReentrantLock();
private int apple = 50;
public static void main(String[] args) {
Demo5 demo5 = new Demo5();
new Thread(demo5,"小明").start();
new Thread(demo5,"名").start();
new Thread(demo5,"紅").start();
}
@Override
public void run() {
for (int j = 50; j >=0; j--) {
eat();
}
}
//同步鎖:(Lock)
//Lock機制提供了比synchronized代碼塊和synchronized方法更廣泛的確定性操作,
//同步代碼塊/同步方法具有的功能都有,除此之外更加強大,更體現面對對象
private void eat(){
lock.lock();//獲取鎖
if (apple>0) {
try{
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"吃了"+apple+"蘋果");
apple--;
}catch(Exception e){
e.printStackTrace();
}finally{
lock.unlock();//釋放鎖
}
}
}
}
package com.anonymous.javase.day06;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//生產者
class ProducerTest implements Runnable {
private ShareDemo6 share = new ShareDemo6();
public ProducerTest(ShareDemo6 share){
this.share = share;
}
@Override
public void run() {
for (int i = 1; i <= 50 ; i++) {
if (i % 2 == 0) {
share.setArgs("JACK", "男");
}else{
share.setArgs("ROSE", "女");
}
}
}
}
//消費者
class CustomerTest implements Runnable{
private ShareDemo6 share = new ShareDemo6();
public CustomerTest(ShareDemo6 share){
this.share = share;
}
@Override
public void run(){
for (int i = 1; i <= 50; i++) {
share.pass();
}
}
}
public class ShareDemo6 {
private String name ;
private String gender ;
private boolean stauts = true ;//表示生產者生產數據爲空
private Lock lock =new ReentrantLock();
Condition con = lock.newCondition();
//生產者生產數據
public void setArgs(String name,String gender){
lock.lock();
try {
if(!stauts){//
con.await();
}
Thread.sleep(10);
this.name = name;
this.gender = gender;
stauts = false;
con.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
//消費者消費數據
public void pass(){
lock.lock();
try {
if(stauts){
con.await();
}
Thread.sleep(10);
System.out.println(this.name+"_"+this.gender);
stauts = true;
con.signal();
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
public static void main(String[] args) {
ShareDemo6 share = new ShareDemo6();
new Thread(new ProducerTest(share)).start();
new Thread(new CustomerTest(share)).start();
}
}
線程的生命週期:
線程睡眠:
package com.anonymous.javase.day06; public class Demo7 { //線程睡眠 public static void main(String[] args) { for (int i = 1; i <= 20; i++) { try { Thread.sleep(1000);//毫秒數 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(i); } } }
package com.anonymous.javase.day06;
//聯合線程
class JoinThread extends Thread{
public JoinThread(String name){
super(name);
}
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
System.out.println(super.getName()+"join"+i);
}
}
}
public class Demo8 {
/**
* 聯合線程:
* 線程的join方法,表示一個線程等待另一個線程完成後才執行,join方法被調用之後,線程對象處於阻塞狀態
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
JoinThread joinThread = new JoinThread("String");
for (int i = 1; i <= 50; i++) {
System.out.println("main線程"+i);
if(i==5){
joinThread.start();
}
if(i==20){//join()表示強制讓出線程運行
joinThread.join();
}
}
}
}
package com.anonymous.javase.day06;
//後臺線程
class DeamonTest extends Thread{
@Override
public void run() {
for (int i = 1; i <= 500; i++) {
System.out.println("傑克"+i);
}
}
}
public class Demo9 {
public static void main(String[] args) {
DeamonTest test = new DeamonTest();
boolean daemon = test.isDaemon();
System.out.println(daemon);
for (int i = 1; i <= 50; i++) {
System.out.println("main線程"+i);
if (i==10) {
test.setDaemon(true);
test.start();
System.out.println(test.isDaemon());
}
}
}
}