0% found this document useful (0 votes)
1 views14 pages

Recap 06062025

Uploaded by

truong giang
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
1 views14 pages

Recap 06062025

Uploaded by

truong giang
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

6/6/2025

3.11. Collection, Map (continue)


Distinguish ConcurrentHashMap and HashMap
Feature HashMap ConcurrentHashMap

Thread-safe No Yes

No (manually synchronized if
Synchronized Internally synchronized
needed)

Concurrency Poor High

Allow null keys Yes No

Allow null values Yes No

Example HashMap:

package day4.collectionmap;

import java.util.HashMap;
import java.util.Map;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class HashMapConcurrencyExample {


public static void main(String[] args) throws InterruptedException {
Map<String, String> map = new HashMap<>();

Runnable writer1 = () -> {


for (int i = 0; i < 1000; i++) {
map.put("A_key" + i, "value" + i); // Thread 1: A_key0 to A_key999
}
};

Runnable writer2 = () -> {


for (int i = 0; i < 1000; i++) {
map.put("B_key" + i, "value" + i); // Thread 2: B_key0 to B_key999
}
};

Thread t1 = new Thread(writer1);


Thread t2 = new Thread(writer2);

t1.start();
t2.start();
t1.join();

6/6/2025 1
t2.join();

System.out.println("Map size: " + map.size()); // Should now be 2000


}
}

Result: Data loss because HashMap is not thread-safe

Example ConcurrentHashMap:

package day4.collectionmap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {


public static void main(String[] args) throws InterruptedException {
Map<String, String> map = new ConcurrentHashMap<>();

Runnable writer1 = () -> {


for (int i = 0; i < 1000; i++) {
map.put("A_key" + i, "value" + i); // Thread 1: A_key0 to A_key999
}
};

Runnable writer2 = () -> {


for (int i = 0; i < 1000; i++) {
map.put("B_key" + i, "value" + i); // Thread 2: B_key0 to B_key999
}
};

Thread t1 = new Thread(writer1);


Thread t2 = new Thread(writer2);

t1.start();
t2.start();
t1.join();

6/6/2025 2
t2.join();

System.out.println("Map size: " + map.size()); // Should now be 2000


}
}

Result:

Demo exercise on Map, Collection:

package day4.collectionmap;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Scanner;

public class Exercise1 {


public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String[] strings = s.split(" ");
Map<String, Integer> map = new LinkedHashMap<>();
for(var item : strings){
if(map.containsKey(item)){
map.put(item, map.get(item) + 1);
} else {
map.put(item, 1);
}
}
for(var it : map.entrySet()){
System.out.println(it.getKey() + ": " + it.getValue() + " times");
}
}
}

6/6/2025 3
3.12. Thread
Demo ways to create thread:

package day4.thread;

import java.util.concurrent.TimeUnit;

class SubThread extends Thread {


@Override
public void run() {
for(int i = 1; i <= 5; i++){
System.out.print(" 1 ");
try {
Thread.sleep(500); //tell Thread to do nothing for certain amount of time
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}

public class ThreadCreationExample {


public static void main(String[] args) {
var currentThread = Thread.currentThread();
System.out.println(currentThread);
//Solution 1 to create thread: extending Thread class
SubThread thread1 = new SubThread();
thread1.start();

//Solution 2 to create thread: implementing Runnable interface


Runnable myRunnable = () -> {
for(int i = 1; i <= 8; i++){
System.out.print(" 2 ");

6/6/2025 4
try {
TimeUnit.MILLISECONDS.sleep(250);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread2 = new Thread(myRunnable);
//print 2:
thread2.start();
}
}

Demo start, stop, join on thread:

public class ThreadStateExample {


public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
Thread.sleep(1000); // TIMED_WAITING
} catch (InterruptedException e) {
e.printStackTrace();
}
});

System.out.println(t.getState()); // NEW
t.start();
System.out.println(t.getState()); // RUNNABLE
Thread.sleep(100); // give time for thread to enter sleep
System.out.println(t.getState()); // TIMED_WAITING
t.join();
System.out.println(t.getState()); // TERMINATED
}
}

Thread states

6/6/2025 5
1. NEW
Created using new Thread(...) , but not yet started.

Thread t = new Thread(); // t.getState() == NEW

2. RUNNABLE
Thread is either running or ready to run (depends on CPU availability).

t.start(); // moves from NEW → RUNNABLE

3. BLOCKED
Waiting to acquire a lock (monitor) to enter a synchronized block/method.

Happens when another thread holds the lock.

synchronized(lock) { // another thread is holding this


// blocked until lock is released
}

4. WAITING
Thread is waiting indefinitely for another thread's action (no timeout).

Methods that cause this:

Object.wait()

Thread.join()

LockSupport.park()

5. TIMED_WAITING
Thread waits for a specific time before becoming RUNNABLE again.

Common methods:

Thread.sleep(ms)

6/6/2025 6
join(ms)

wait(ms)

LockSupport.parkNanos()

6. TERMINATED
Thread has completed or was stopped with an uncaught exception.

if (!t.isAlive()) {
System.out.println("Thread terminated");
}

Demo Thread states:

public class ThreadStateExample {


public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
try {
Thread.sleep(1000); // TIMED_WAITING
} catch (InterruptedException e) {
e.printStackTrace();
}
});

System.out.println(t.getState()); // NEW
t.start();
System.out.println(t.getState()); // RUNNABLE
Thread.sleep(100); // give time for thread to enter sleep
System.out.println(t.getState()); // TIMED_WAITING
t.join();
System.out.println(t.getState()); // TERMINATED
}
}

Distinguish between thread and process


Feature Process Thread

6/6/2025 7
A self-contained unit of
A lightweight unit of execution
Definition execution with its own memory
within a process
space

- Shares the process memory


(heap) with other threads in the
Has its own memory space
Memory same process
(heap)
- Each thread has its own
memory (stack)

Communication between
Threads easily share data via
Communication processes is complex (IPC:
shared memory
pipes, sockets, etc.)

Processes are isolated from Threads are not isolated (can


Isolation
each other affect each other’s data)

Higher (needs new memory Lower (lighter, shares process


Creation Overhead
space, OS resources) context)

If one process crashes, others If one thread crashes, it can


Crash Impact
are unaffected crash the entire process

Running independent apps or Performing concurrent tasks


Use Case
services within one app

Common problems when using thread


1. Race conditions

2 or more threads access shared resource at the same time, and at least one thread modifies it.
→ unexpected behavior or corrupt data

2. Deadlocks

2 or more threads are waiting on each other to release locks, but none ever proceed.

3. Starvation

A thread never gets CPU time or access to resources because others dominate.

4. Memory consistency errors

1 thread updates a shared variable, but another thread doesn’t see the change due to caching
or reordering

Exercise on thread:

package day4.thread;

import java.util.Random;
class Horse implements Runnable {

private final int id;


private int distance = 0;
private int steps = 0;
private final Random random = new Random();

public Horse(int id) {

6/6/2025 8
this.id = id;
}

@Override
public void run() {
while (true) {
try {
Thread.sleep(500); // wait 0.5 second
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}

int sizeOfOneStep = random.nextInt(10) + 1; // 1 to 10


distance += sizeOfOneStep;
steps++;
if (distance == 100) {
System.out.printf("Horse %d has reached the finish line with %d steps!%n", id, steps);
break;
} else if (distance > 100) {
distance = distance - 100; //in this case, distance will be equal to its difference with 100
}
// System.out.printf("Horse %d ran %d meters (total: %d)%n", id, step, distance);
}
}
}

public class Exercise2 {


public static void main(String[] args) {
int horseCount = 10;
for (int i = 1; i <= horseCount; i++) {
Thread horseThread = new Thread(new Horse(i));
horseThread.start();
}
}
}

6/6/2025 9
3.14. Reflection
Reflection:

inspect and manipulate classes, methods, fields and components at runtime

allow inspecting and processing metadata at runtime

instantiate objects dynamically using Class.forName() and newInstance()

accessing members: access private fields and methods using setAccessible(true)

invoking methods: invoke methods using Method.invoke()

Demo export import file CSV using Reflection:

package day4.reflection;

import java.util.Arrays;
import java.util.List;

public class ReflectionExample {


public static void main(String[] args) throws Exception {
List<Student> people = Arrays.asList(
new Student("Alice", 30, "alice@example.com"),
new Student("Bob", 25, "bob@example.com"),
new Student("Mike", 23, "mike@example.com"),
new Student("Michael", 27, "michael@example.com")
);

String filePath = "people.csv";

// Export
CsvExporter.exportToCsv(people, filePath);

6/6/2025 10
// Import
List<Student> imported = CsvImporter.importFromCsv(filePath, Student.class);

imported.forEach(p -> System.out.println(p.getName() + ", " + p.getAge() + ", " + p.getEmail()


}
}

package day4.reflection;

import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;

public class CsvExporter {

public static void exportToCsv(List<?> objects, String filePath) throws IOException, IllegalAcces
if (objects == null || objects.isEmpty()) return;

Class<?> aClass = objects.get(0).getClass();


Field[] fields = aClass.getDeclaredFields();

try (FileWriter writer = new FileWriter(filePath)) {


// Header
for (int i = 0; i < fields.length; i++) {
writer.append(fields[i].getName());
if (i < fields.length - 1) writer.append(",");
}
writer.append("\n");

// Data rows
for (Object obj : objects) {
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
Object value = fields[i].get(obj);
writer.append(value != null ? value.toString() : "");
if (i < fields.length - 1) writer.append(",");
}
writer.append("\n");
}
}
}
}

package day4.reflection;

6/6/2025 11
import java.io.BufferedReader;
import java.io.FileReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class CsvImporter {

public static <T> List<T> importFromCsv(String filePath, Class<T> clazz) throws Exception {
List<T> list = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
String headerLine = br.readLine(); // skip headers
if (headerLine == null) return list;

String[] headers = headerLine.split(",");

String line;
while ((line = br.readLine()) != null) {
String[] values = line.split(",");
T instance = clazz.getDeclaredConstructor().newInstance();

for (int i = 0; i < headers.length; i++) {


Field field = clazz.getDeclaredField(headers[i]);
field.setAccessible(true);
Class<?> type = field.getType();
Object value = parseValue(values[i], type);
field.set(instance, value);
}

list.add(instance);
}
}
return list;
}

private static Object parseValue(String str, Class<?> type) {


if (type == int.class || type == Integer.class) return Integer.parseInt(str);
if (type == double.class || type == Double.class) return Double.parseDouble(str);
if (type == boolean.class || type == Boolean.class) return Boolean.parseBoolean(str);
return str;
}
}

package day4.reflection;

public class Student {


private String name;

6/6/2025 12
private int age;
private String email;

public Student() {} // Required for reflection

public Student(String name, int age, String email) {


this.name = name;
this.age = age;
this.email = email;
}

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public int getAge() {


return age;
}

public void setAge(int age) {


this.age = age;
}

public String getEmail() {


return email;
}

public void setEmail(String email) {


this.email = email;
}
}

Result:

6/6/2025 13
6/6/2025 14

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy